// Copyright (C) 1997 Keith Whitwell. // This file may only be copied under the terms of the GNU Library General // Public License - see the file COPYING in the lib3d distribution. // This file is contributed by // Markus F.X.J. Oberhumer #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(__MSDOS__) #include #endif /*********************************************************************** // helper functions ************************************************************************/ Model * createCube ( float width, float height, float depth, Vector3 const &col, int face = PrimitiveModelBuilder::FACE_OUTSIDE ) { PrimitiveModelBuilder *mb = new PrimitiveModelBuilder; if (!mb) return 0; mb->calculatePolygonNormals(); mb->calculateVertexNormals(); mb->startModel(); mb->addMaterial(col, .2,1,0,0,0); mb->addCube(width,height,depth,face); Model *m = mb->endModel(); delete mb; return m; } Model * createCube ( float size, Vector3 const &col, int face = PrimitiveModelBuilder::FACE_OUTSIDE ) { return createCube(size,size,size,col,face); } /*********************************************************************** // ************************************************************************/ int main(int argc) { // helper variables ulong nrFrames = 0; // create device & viewport Viewport *viewport = Viewport::create( Device::create( 320, 200, 8 ) ); if (!viewport) { cout << "Failed to create viewport" << endl; exit(1); } // create world World world; // create camera Camera *camera = new Camera( world ); camera->setParameters( 3, 1000, 15, 1 ); Matrix34 tcam; tcam.setTranslation( 0, 0, -250 ); camera->setTransform( tcam ); world.setActiveCamera( *camera ); // create light Vector3 lcolour(1,1,1); // A white light Vector3 ldirection(0,1,.5); Light *light = new Light(world); light->setParameters(lcolour, lcolour, ldirection); world.registerLight( *light ); if (argc > 1) { // create background Model *floor = createCube(120, 0,500, Vector3(.3,.3,.0)); Model *back = createCube(120,120, 0, Vector3(.4,.2,.0)); #if 0 // for Z-buffer timing purposes: put a rectangle just behind 'back' // completly invisible: //Model *back2 = createCube(120,120, 0, Vector3(.6,.2,.0)); // mostly invisible: Model *back2 = createCube(140,140, 0, Vector3(.6,.1,.0)); #else Model *back2 = 0; #endif // set position of the floor to height -60 (sign of y coord !) Matrix34 t; t.setTranslation( 0, 60, -150 ); if (floor) floor->setTransform( t ); t.setTranslation( 0, 0, 100 ); if (back) back->setTransform( t ); t.setTranslation( 0, 0, 110 ); if (back2) back2->setTransform( t ); // put background into the world if (floor) world.adopt( floor ); if (back) world.adopt( back ); if (back2) world.adopt( back2 ); } // create models (3 colored cubes) Model *cube1 = createCube(20, Vector3(.8,.0,.0)); Model *cube2 = createCube(20, Vector3(.0,.8,.0)); Model *cube3 = createCube(20, Vector3(.0,.0,.8)); // set position of the models Matrix34 tcube1, tcube2, tcube3; tcube1.setTranslation( -40, 10, 0 ); tcube2.setTranslation( 0, 0, 0 ); tcube3.setTranslation( 40, -10 , 0 ); cube1->setTransform( tcube1 ); cube2->setTransform( tcube2 ); cube3->setTransform( tcube3 ); // put models into the world (under a 'cubes' subtree) Node *cubes = new Node; world.adopt( cubes ); cubes->adopt( cube1 ); cubes->adopt( cube2 ); cubes->adopt( cube3 ); // prepare cube rotation Matrix34 rcube1, rcube2, rcube3; rcube1.setRotation( -M_PI / 10, 1, 0, 0 ); // rotate about X axis rcube2.setRotation( -M_PI / 5, 0, 1, 0 ); // rotate about Y axis rcube3.setRotation( -M_PI / 7, 0, 0, 1 ); // rotate about Z axis // use different pipeline (strange display problems and crashes ???) #if 0 Pipeline *smoothpipe = new SmoothPipeline; //cubes->usePipeline( *smoothpipe ); // not allowed ??? cube2->usePipeline( *smoothpipe ); #endif // for moving the cube float cubes_y = 0; float cubes_dy = 0.2; // for moving the camera float cam_z = -250; float cam_dz = 0.3; HrTimer clip("Clipping"); clip.start(); for ( int i = 0 ; i < 100000 ; i++ ) { // calc new up/down position cubes_y += cubes_dy; if ( fabs( cubes_y ) >= 40 ) cubes_dy = - cubes_dy; // move the cubes object hierachy Matrix34 tcubes; tcubes.setTranslation( 0, cubes_y, 0 ); cubes->setTransform( tcubes ); // animate single cubes tcube1.postmul( rcube1 ); cube1->setTransform( tcube1 ); tcube2.postmul( rcube2 ); cube2->setTransform( tcube2 ); tcube3.postmul( rcube3 ); cube3->setTransform( tcube3 ); // calc new camera position cam_z += cam_dz; if ( cam_z > -220 || cam_z < -280) cam_dz = - cam_dz; // set camera position tcam.setTranslation( 0, 0, cam_z ); camera->setTransform( tcam ); // display it world.renderHierarchy( *viewport ); viewport->swapBuffers(); nrFrames++; #if defined(__MSDOS__) if (kbhit()) break; #endif } clip.end(); // call destructor delete viewport; // this also deletes the device // now back in text mode cout << clip; cout << " " << (float(nrFrames)/clip.getElapsedSeconds()) << " frames per second" << endl; return 0; }