#ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #ifdef HAVE_GL_GL_H # include #elif HAVE_OPENGL_GL_H # include #endif #ifdef HAVE_GL_GLU_H # include #elif HAVE_OPENGL_GLU_H # include #endif #include #include "anugavis.hh" #include "height_quantity.hh" #include "sww_file.hh" using boost::bind; using boost::shared_ptr; using std::for_each; using std::string; AnugaVis::AnugaVis(const string &file_name, int width, int height): frame(0), paused(false), screen(NULL), sww_file(new SWWFile(file_name)){ init_camera(); init_SDL(width, height); init_OpenGL(width, height); } AnugaVis::~AnugaVis(void){ if(this->screen != NULL) SDL_Quit(); } void AnugaVis::add_HeightQuantity(shared_ptr &height){ height->set_SWWFile(this->sww_file); this->heights.push_back(height); } void AnugaVis::run(void){ while(this->step()); } void AnugaVis::init_camera(void){ this->eye = Vector(this->sww_file->minX, this->sww_file->minY, 0); this->focus = Vector(this->sww_file->minX + (this->sww_file->maxX - this->sww_file->minX) / 2, this->sww_file->minY + (this->sww_file->maxY - this->sww_file->minY) / 2, 0); this->eye.z = (eye - focus).magnitude(); } void AnugaVis::init_SDL(int width, int height){ if((SDL_Init(SDL_INIT_VIDEO) == -1) || (SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5) == -1) || (SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5) == -1) || (SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5) == -1) || (SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16) == -1) || (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) == -1) || ((this->screen = SDL_SetVideoMode(width, height, 16, SDL_OPENGL)) == NULL)) throw SDL_GetError(); SDL_WM_SetCaption("ANUGA Visualiser", "ANUGA Visualiser"); } void AnugaVis::init_OpenGL(int width, int height){ GLfloat lightAmbient[] = {0.0, 0.0, 0.0, 1.0}; GLfloat lightDiffuse[] = {1.0, 1.0, 1.0, 1.0}; glEnable(GL_DEPTH_TEST); glShadeModel(GL_FLAT); glEnable(GL_NORMALIZE); glMatrixMode(GL_PROJECTION); gluPerspective(45.0, ((GLdouble)width)/((GLdouble)height), 0.1, 1000); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); } static const Uint32 TARGET_TICK_RATE = 50; bool AnugaVis::step(void){ static Uint32 ticks = 0; static Uint32 lastframe; bool more = true; float light[4]; if(ticks == 0) lastframe = ticks = SDL_GetTicks(); else ticks = SDL_GetTicks(); if(ticks - lastframe < TARGET_TICK_RATE) return more; lastframe = ticks; if(this->frame < this->sww_file->number_of_timesteps - 1){ if(!this->paused) this->frame++; }else this->paused = 1; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(this->eye .x, this->eye .y, this->eye .z, this->focus.x, this->focus.y, this->focus.z, 0, 0, 1); light[0] = this->eye.x; light[1] = this->eye.y; light[2] = this->eye.z; light[3] = 1.0; glLightfv(GL_LIGHT0, GL_POSITION, light); for_each(this->heights.begin(), this->heights.end (), bind(&HeightQuantity::draw, _1, this->frame)); return false; }