/* * Example menu universe * This universe is run when the application starts (in this demo) by * main-universe. * * It is supposed to present a menu before the main gameplay (which is supposed to be * implemented in game-universe) is accessed. * * To switch between universes, set next_universe to one of the universes listed * in universes-enum.h * */ #include "menu-universe.h" #define TTL 20000.0 #define START_POS -10.0+rand_range(2000)/100.0 extern mjApplication App; // Global application control variable void MenuUniverse::Init() { /* * This method must be used to define initial graphical aspects, as well as * the initial values of variables. */ init_cam_ctl_def(&camera); vector3 g; v3_est(0, -1, 0, &g); //mjEnableSimpleLighting(); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); snowTex = mjGLTextureFromFile("resources/snowtex.png"); bgTex = mjGLTextureFromFile("resources/bg.jpg"); mjEnableSimpleTexturing(ALPHA_ON); b = new mjBillboard(&camera.pos); b->tex = bgTex; v3_est(0, 0, -30, &b->p); v3_est(50,50,50, &b->scale); glClearColor(0.1, 0.1, 0.6, 1.0); p.SetGravity(g); for (int r = 0; r < 350; r++) { mjBillboard * newBill = new mjBillboard(&camera.pos); v3_est(START_POS, 10+START_POS ,-20+START_POS , &newBill->p); newBill->tex = snowTex; snow.push_back(newBill); p.AddObject(newBill); newBill->ttl = TTL*(rand_range(100)/100.0); } } void MenuUniverse::ProcessEvent(s_event & event) { /* * In this method, game variables must be modified according to user * input. * These variables will be used in the Update method. * */ if (event.quit) { debug("Quitting menu universe\n"); SetNextUniverse(NULL); return; } switch(event.key_down){ case 'a':{ camera.dsc_ctl.fwd = 1; } break; case 'z':{ camera.dsc_ctl.backwd = 1; } break; case 'q':{ camera.dsc_ctl.spin_CCW = 1; } break; case 'w':{ camera.dsc_ctl.spin_CW = 1; } break; case ARROWUP:{ camera.dsc_ctl.spin_nosedown = 1; } break; case ARROWDOWN:{ camera.dsc_ctl.spin_noseup = 1; } break; case ARROWLEFT:{ camera.dsc_ctl.spin_left = 1; } break; case ARROWRIGHT:{ camera.dsc_ctl.spin_right = 1; } break; } switch(event.key_up){ case 'a':{ camera.dsc_ctl.fwd = 0; } break; case 'z':{ camera.dsc_ctl.backwd = 0; } break; case 'q':{ camera.dsc_ctl.spin_CCW = 0; } break; case 'w':{ camera.dsc_ctl.spin_CW = 0; } break; case ARROWUP:{ camera.dsc_ctl.spin_nosedown = 0; } break; case ARROWDOWN:{ camera.dsc_ctl.spin_noseup = 0; } break; case ARROWLEFT:{ camera.dsc_ctl.spin_left = 0; } break; case ARROWRIGHT:{ camera.dsc_ctl.spin_right = 0; } break; } } void MenuUniverse::Update(float t_elapsed) { /* * This method is used to update (i.e. "modify") the game variables and game * flow according to the user input values read previously. By dividing it * into two steps (ProcessEvent and Update), the game can respond to * more abstract signals, such as toggling switches to modify settings, * etc. * Now, the elapsed time since the last time this method was run (in other * words, since last frame), must be taken into account. */ std::list::iterator i_b; update_cam_auto(&camera); // Add a bit of random movement i_b = snow.begin(); while (i_b != snow.end()) { vector3 e; mjBillboard * s; s = *i_b; if (s->ttl > 0) { v3_est(-2 + rand_range(4000)/1000.0, -2 + rand_range(4000)/1000.0, -2 + rand_range(4000)/1000.0, &e); s->ApplyEffect(e, s->p, PE_ACCEL); s->ttl -= t_elapsed; } else { v3_est(START_POS, 10+START_POS , -20+START_POS, &s->p); v3_0(&s->v); s->ttl = TTL*(rand_range(100)/100.0); } i_b++; } p.Update(t_elapsed); } void MenuUniverse::Redraw(void) { /* * This method is used to display the current universe's state using OpenGL * commands. * * No updating of variables should take place in this method. * */ vector3 pos; vector3 antiDir; vector3 up; std::list::iterator i_b; v3_est( 0.0, 0.0, -5,&pos); v3_j(&up); vec_copy(pos, &antiDir); vec_sum(-1, camera.pos, &antiDir); antiDir.y = 0; normalize(&antiDir); //vec_sum(-1, camera.dir, &antiDir); glLoadIdentity(); gluLookAt(camera.pos.x, camera.pos.y, camera.pos.z, camera.pos.x+camera.dir.x, camera.pos.y+camera.dir.y, camera.pos.z+camera.dir.z, camera.dirv.x, camera.dirv.y, camera.dirv.z); mjDefLightPos(); //glTranslatef( 0, 0, -5); push(); //glScaled(20, 20, 20); //glColor3f(0,1,0); //mjPlane(1, 1); pop(); glColor3f(1,1,1); //b->Draw(); //obj_pos_rot(pos, antiDir, up); i_b = snow.begin(); glDisable(GL_DEPTH_TEST); while (i_b != snow.end()) { mjBillboard * s; s = *i_b; s->Draw(); i_b++; } glEnable(GL_DEPTH_TEST); } void MenuUniverse::Cleanup(void) { /* * When switching universes, it can be specified whether or not to run this * method. It is intended for this method to free dynamically allocated * memory (running "delete" on objects, etc.), for example, *this* * universe's state will not need to be preserved because it will not be * re-visited or it can be "reset" to its original state when re-visited. * * However if this universe needs to preserve its state so it can be used * where it was left off, it could be marked as not wanting to be cleaned up * and not wanting to be initialized again on switching. * */ }