//**************************************************************************** //! \file wengine.cpp //! \date 06-03-2003 //***************************************************************************** // This file is part of the Weird Demo. // // The Weird Demo is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // The Weird Demo is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with DataView; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "wengine.hpp" //*************************************************************************** // WEngine methods //*************************************************************************** // public methods //*************************************************************************** //*************************************************************************** WEngine::WEngine( QWidget *parent, char const *name): GLView(parent,name) //*************************************************************************** { object = 0; texanim=0; switcher = false; } //*************************************************************************** WEngine::~WEngine() //*************************************************************************** { } //*************************************************************************** void WEngine::Init( const unsigned int sm, const unsigned int df, const int in) //*************************************************************************** { GLView::Init( sm, df, in); } //*************************************************************************** void WEngine::evKeyPress( QKeyEvent *k) //*************************************************************************** { switch ( k->key()) { case Qt::Key_O: if( switcher)ois.push_back( *( new TGLObject( &object, 0, 0, 0, 0.1, 0.111111, 0.3333333, 0, 0, 0, 5, 5, 5))); else ois.push_back( *( new TGLObject( &tetra, 0, 0, 0, -0.1, -0.111111, -0.3333333, 0, 0, 0, 5, 5, 5))); switcher = !switcher; update(); break; case Qt::Key_T: ois.push_back( *( new TGLObject( &transo, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); update(); break; case Qt::Key_M: mswitch = ! mswitch; makeTexObject(); update(); break; case Qt::Key_C: ois.push_back( *( new TGLObject( &texo, 0, 0, 0, /*0.1, 0.111111, 0.1333333,*/0, 0, 0, 0, 0, 0, 0,0,0/*2, 2, 2*/))); update(); break; } } //*************************************************************************** // protected methods //*************************************************************************** //*************************************************************************** void WEngine::director() //*************************************************************************** { for( itois = ois.begin(); itois!=ois.end(); ++itois) { if( ( itois->x>5.)||( itois->x<-5.)) { itois->vx*=-1.; } if( ( itois->y>5.)||( itois->y<-5.)) { itois->vy*=-1.; } if( ( itois->z>5.)||( itois->z<-5.)) { itois->vz*=-1.; } } for( itlights = lights.begin(); itlights!=lights.end(); ++itlights) { if( ( itlights->x>15.)||( itlights->x<-15.)) { itlights->vx*=-1.; } if( ( itlights->y>15.)||( itlights->y<-15.)) { itlights->vy*=-1.; } if( ( itlights->z>15.)||( itlights->z<-15.)) { itlights->vz*=-1.; } if( itlights->kind==GL_DIFFUSE)itlights->Color( itlights->x/30.+.5, itlights->y/30.+.5, itlights->z/30.+.5); } } //*************************************************************************** void WEngine::adjustLights() //*************************************************************************** { for( itlights = lights.begin(); itlights!=lights.end(); itlights++) { itlights->x+=itlights->vx; itlights->y+=itlights->vy; itlights->z+=itlights->vz; GLfloat LPos[4]= { itlights->x, itlights->y, itlights->z, 1.0f }; glLightfv( itlights->id, GL_POSITION, LPos); } } //*************************************************************************** void WEngine::adjustCamera() //*************************************************************************** { Cam->x+=Cam->vx; Cam->y+=Cam->vy; Cam->z+=Cam->vz; Cam->ax+=Cam->vax; Cam->ay+=Cam->vay; Cam->az+=Cam->vaz; } //*************************************************************************** void WEngine::adjustScene() //*************************************************************************** { scene = glGenLists( 1); glNewList( scene, GL_COMPILE ); for( itois = ois.begin(); itois!=ois.end(); ++itois) { itois->ax+=itois->vax; itois->ay+=itois->vay; itois->az+=itois->vaz; itois->x+=itois->vx; itois->y+=itois->vy; itois->z+=itois->vz; glPushMatrix(); glTranslated( itois->x, itois->y, itois->z); glRotated( itois->ax, 1., 0., 0. ); glRotated( itois->ay, 0., 1., 0. ); glRotated( itois->az, 0., 0., 1. ); glCallList( *( itois->obj)); glPopMatrix(); } if( sswitch)for( itshades = shades.begin(); itshades!=shades.end(); ++itshades) { glCallList( *itshades); } glEndList(); } //*************************************************************************** void WEngine::makeShades() //*************************************************************************** { double cub[8][3] = { { 1., 1., 1.}, { -1., 1., 1.}, {-1., 1., -1.}, { 1., 1., -1.}, { -1., -1., -1.}, { 1., -1., -1.}, { 1., -1., 1.}, { -1., -1., 1.}}; double trafo[8][3]; double v[3]; double sp[8][3]; double t; bool tester; glBlendFunc( GL_SRC_ALPHA, GL_ONE); unsigned int shade; for( itois = ois.begin(); itois!=ois.end(); ++itois)if( ( *itois->obj) == texo) { for( int i = 0; i<8; ++i) { trafo[i][0]= cub[i][0]+itois->x; trafo[i][1]= cub[i][1]+itois->y; trafo[i][2]= cub[i][2]+itois->z; } for( itlights = lights.begin(); itlights!=lights.end(); ++itlights)if( itlights->kind==GL_DIFFUSE) { tester = true; for( int i = 0; i<8; ++i) { v[0] = trafo[i][0]-itlights->x; v[1] = trafo[i][1]-itlights->y; v[2] = trafo[i][2]-itlights->z; t = ( -15.-trafo[i][1])/v[1]; tester = tester && (t>=0); if( tester) { sp[i][0]=v[0]*t+itlights->x; sp[i][1]=-15.+0.01; sp[i][2]=v[2]*t+itlights->z; } } if( tester) { shade = glGenLists( 1); shades.push_back( *(new unsigned int(shade))); glNewList( shade, GL_COMPILE ); glColor4d(0., 0., 0., .5); // glEnable( GL_BLEND); // glDisable( GL_DEPTH_TEST); // glEnable( GL_ALPHA_TEST); glDisable( GL_LIGHTING); glBegin( GL_QUADS); for( int i = 0; i<8; i++)glVertex3d( sp[i][0], sp[i][1], sp[i][2]); for( int i = 0; i<8; i+=2)glVertex3d( sp[i][0], sp[i][1], sp[i][2]); for( int i = 1; i<8; i+=2)glVertex3d( sp[i][0], sp[i][1], sp[i][2]); glEnd(); glEnable( GL_LIGHTING); // glDisable( GL_BLEND); // glEnable( GL_DEPTH_TEST); // glDisable( GL_ALPHA_TEST); glEndList(); } } } } //*************************************************************************** void WEngine::initializeGL() //*************************************************************************** { GLView::initializeGL(); quad=gluNewQuadric(); gluQuadricNormals( quad, GLU_SMOOTH); // gluQuadricTexture( quad, GL_TRUE); gluQuadricOrientation( quad, GLU_OUTSIDE); makeObject(); makeTetra(); makeTransObject(); makeTexObject(); makeCont(); } //*************************************************************************** // private methods //*************************************************************************** //*************************************************************************** void WEngine::makeTetra() //*************************************************************************** { tetra = glGenLists( 1); glNewList( tetra, GL_COMPILE ); qglColor( white); glBegin( GL_TRIANGLES); glNormal3d( 0., 1., 2.); glVertex3d( 0., 0.0866, 0.); glVertex3d(-0.1,-0.0866, 0.0866); glVertex3d( 0.1,-0.0866, 0.0866); glNormal3d( 3.464, 1., -2.); glVertex3d( 0., 0.0866, 0.); glVertex3d( 0.,-0.0866, 0.0866); glVertex3d( 0.,-0.0866, -0.0866); glNormal3d( -3.464, 1., -2.); glVertex3d( 0., 0.0866, 0.); glVertex3d( 0.,-0.0866, -0.0866); glVertex3d(-0.1,-0.0866, 0.0866); glNormal3d( 0., -1., 0.); glVertex3d( 0., -0.0866, -0.0866); glVertex3d( -0.1,-0.0866, 0.0866); glVertex3d(0.1,-0.0866, 0.0866); glEnd(); glEndList(); } //*************************************************************************** void WEngine::makeObject() //*************************************************************************** { object = glGenLists( 1); glNewList( object, GL_COMPILE ); glTranslated( -0.13, 0, 0); gluSphere( quad, 0.15f, 32, 32); glTranslated( 0.26, 0, 0); gluSphere( quad, 0.15f, 32, 32); glTranslated( -0.13, 0, 0); glEndList(); } //*************************************************************************** void WEngine::makeTransObject() //*************************************************************************** { glBlendFunc( GL_SRC_ALPHA, GL_ONE);//_MINUS_SRC_ALPHA); // glAlphaFunc( GL_GEQUAL, 0.6); transo = glGenLists( 1); glNewList( transo, GL_COMPILE ); glEnable( GL_BLEND); glDisable( GL_DEPTH_TEST); glEnable( GL_ALPHA_TEST); glColor4d(0., 0., .3, 0.1); gluSphere( quad, 1.73205, 32, 32); glDisable( GL_BLEND); glEnable( GL_DEPTH_TEST); glDisable( GL_ALPHA_TEST); glEndList(); } //*************************************************************************** void WEngine::makeTexObject() //*************************************************************************** { texo = glGenLists( 1); glNewList( texo, GL_COMPILE ); glEnable( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, textures["crate"]); glBegin(GL_QUADS); glNormal3d( 0., 0., 1.); glTexCoord2d(0., 0.); glVertex3d(-1., -1., 1.); glTexCoord2d(1., 0.); glVertex3d( 1., -1., 1.); glTexCoord2d(1., 1.); glVertex3d( 1., 1., 1.); glTexCoord2d(0., 1.); glVertex3d(-1., 1., 1.); glNormal3d( 0., 0.,-1.); glTexCoord2d(1., 0.); glVertex3d(-1., -1., -1.); glTexCoord2d(1., 1.); glVertex3d(-1., 1., -1.); glTexCoord2d(0., 1.); glVertex3d( 1., 1., -1.); glTexCoord2d(0., 0.); glVertex3d( 1., -1., -1.); glNormal3d( 0., 1., 0.); glTexCoord2d(0., 1.); glVertex3d(-1., 1., -1.); glTexCoord2d(0., 0.); glVertex3d(-1., 1., 1.); glTexCoord2d(1., 0.); glVertex3d( 1., 1., 1.); glTexCoord2d(1., 1.); glVertex3d( 1., 1., -1.); glNormal3d( 0.,-1., 0.); glTexCoord2d(1., 1.); glVertex3d(-1., -1., -1.); glTexCoord2d(0., 1.); glVertex3d( 1., -1., -1.); glTexCoord2d(0., 0.); glVertex3d( 1., -1., 1.); glTexCoord2d(1., 0.); glVertex3d(-1., -1., 1.); glNormal3d( 1., 0., 0.); glTexCoord2d(1., 0.); glVertex3d( 1., -1., -1.); glTexCoord2d(1., 1.); glVertex3d( 1., 1., -1.); glTexCoord2d(0., 1.); glVertex3d( 1., 1., 1.); glTexCoord2d(0., 0.); glVertex3d( 1., -1., 1.); glNormal3d(-1., 0., 0.); glTexCoord2d(0., 0.); glVertex3d(-1., -1., -1.); glTexCoord2d(1., 0.); glVertex3d(-1., -1., 1.); glTexCoord2d(1., 1.); glVertex3d(-1., 1., 1.); glTexCoord2d(0., 1.); glVertex3d(-1., 1., -1.); glEnd(); glDisable( GL_TEXTURE_2D ); glEndList(); } //*************************************************************************** void WEngine::makeCont() //*************************************************************************** { glNewList( cont, GL_COMPILE ); glEnable( GL_TEXTURE_2D ); glEnable( GL_BLEND); glDisable( GL_DEPTH_TEST); glEnable( GL_ALPHA_TEST); glBindTexture(GL_TEXTURE_2D, textures["water"]); glBegin(GL_QUADS); for( int i=-30; i<31; ++i)for( int j=-30; j<31; ++j) { glNormal3d( 0., 1., 0.); glTexCoord2d(2.-(double)texanim/40., 2.-(double)texanim/20.); glVertex3d( i, -15.+0.3*cos( i+j+texanim/(2.*M_PI)), j); glTexCoord2d(1.-(double)texanim/40., 2.-(double)texanim/20.); glVertex3d( i+1., -15.+0.3*cos( i+j+1.+texanim/(2.*M_PI)), j); glTexCoord2d(1.-(double)texanim/40., 1.-(double)texanim/20.); glVertex3d( i+1., -15.+0.3*cos( i+j+2.+texanim/(2.*M_PI)), j+1.); glTexCoord2d(2.-(double)texanim/40., 1.-(double)texanim/20.); glVertex3d( i, -15.+0.3*cos( i+j+1.+texanim/(2.*M_PI)), j+1.); } glEnd(); glDisable( GL_TEXTURE_2D ); glDisable( GL_BLEND); glEnable( GL_DEPTH_TEST); glDisable( GL_ALPHA_TEST); glEndList(); texanim++; if(texanim>39)texanim=0; }