#include "ViewBase.h" #include "ModelBase.h" #include "ControllerBase.h" #include "CameraBase.h" #include "OverlayBase.h" #include "SimpleConsoleOverlay.h" #include "OGLFT.h" #include #include #include "DrawingsGL.h" using namespace std; namespace Engine { static ViewBase* ViewInstance = NULL; void InitGL () { glClearColor(0.3f, 0.3f, 0.3f, 1.0f); glClearDepth(1.0); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glEnable (GL_CULL_FACE); glDisable (GL_FOG); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); } /* * Inherited Module functions */ int ViewBase::OnInit (int argc, char* argv[]) { LogMessage ("View Init"); mWindowHeight = VIEW_DEFAULT_HEIGHT; mWindowWidth = VIEW_DEFAULT_WIDTH; SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); if( SDL_SetVideoMode( mWindowWidth, mWindowHeight, 16, SDL_OPENGL | SDL_RESIZABLE ) == 0 ) { LogError ("Video mode set failed: %s", SDL_GetError ()); exit (-1); } InitGL (); Resize (mWindowWidth, mWindowHeight); LoadFont ("console.ttf"); mCurrentFont = mFonts["console.ttf"]; SetFontColor (1., 1., 1.); // Overlays OverlayBasePtr console_overlay(new SimpleConsoleOverlay); mOverlayManager.Register (console_overlay, 0); //AddOverlay (console_overlay); mDrawGrid = false; mGridSizeX = 8; mGridSizeZ = 8; ViewInstance = this; return 0; } void ViewBase::OnDestroy () { std::map::iterator iter; for (iter = mFonts.begin(); iter != mFonts.end(); ++iter) { delete iter->second; } mFonts.clear(); ViewInstance = NULL; LogDebug ("View Destroy"); } void ViewBase::CalcWorldCoordinates (int screen_x, int screen_y, float world_y, float *pos_out) { GLdouble modelMatrix[16], projMatrix[16]; GLint viewport[4]; GLdouble wx, wy, wz; glGetIntegerv (GL_VIEWPORT, viewport); glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); int realy = viewport[3] - screen_y - 1; gluUnProject ((GLdouble) screen_x, (GLdouble) realy, 1., modelMatrix, projMatrix, viewport, &wx, &wy, &wz); GLdouble t; GLdouble d[3]; float eye[3]; mCamera->GetEye (&eye[0]); d[0] = wx - eye[0]; d[1] = wy - eye[1]; d[2] = wz - eye[2]; assert (fabs (d[1]) >= 1.0e-3); t = -eye[1]/d[1] + world_y; pos_out[0] = eye[0] + t * d[0]; pos_out[1] = eye[1] + t * d[1]; pos_out[2] = eye[2] + t * d[2]; } /* * Module specific functions */ void ViewBase::UpdateCamera () { EntityPhysicState* player_ent = GetEntityPhysicState (GetPlayerEntityId()); if (!player_ent) { LogError ("Could not call Model::PositionCamera(): player entity not found!"); exit (-1); } vector3d entity_camera_distance (-2, 3, 0); vector3d entity_position = player_ent->GetPosition(); player_ent->Globalize (entity_camera_distance); mCamera->SetEye ( entity_camera_distance[0], entity_camera_distance[1], entity_camera_distance[2] ); mCamera->SetPointOfIntrest ( entity_position[0], entity_position[1], entity_position[2] ); mCamera->Update (); } void ViewBase::PreDraw() { // Clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // update the frame rate counter static Uint32 this_frame_ticks; static Uint32 last_frame_ticks = 0; static Uint32 last_fps_update = 0; static int frame_counter = 0; this_frame_ticks = SDL_GetTicks (); last_fps_update += this_frame_ticks - last_frame_ticks; last_frame_ticks = this_frame_ticks; frame_counter++; if (last_fps_update > 1000) { mFrameRate = frame_counter; last_fps_update = 0; frame_counter = 0; } } void ViewBase::Draw () { // Perform pre-Draw actions PreDraw (); // Actual Drawing UpdateCamera (); if (mDrawGrid) DrawGrid (); DrawWorld (); mOverlayManager.Draw(); // Perform post-Draw actions PostDraw(); } void ViewBase::PostDraw() { SDL_GL_SwapBuffers (); } /* Fonts */ bool ViewBase::LoadFont (const char *font_name, float point_size) { std::string font_path ("./data/fonts/"); font_path += font_name; LogDebug ("Loading font %s size %f from %s", font_name, point_size, font_path.c_str()); OGLFT::Monochrome *font = new OGLFT::Monochrome (font_path.c_str(), point_size); if ( font == 0 || !font->isValid() ) { LogError ("Could not load font %s!", font_path.c_str()); return false; } font->setForegroundColor(1., 1., 1.); mFonts.insert(std::make_pair(font_name, font)); return true; } void ViewBase::SelectFont (const char *font) { std::map::iterator font_iter; font_iter = mFonts.find(font); if (font_iter != mFonts.end()) { mCurrentFont = font_iter->second; return; } LogDebug ("Font %s not found, trying to load it", font); if (LoadFont (font)) { font_iter = mFonts.find(font); assert (mFonts.find(font) != mFonts.end()); mCurrentFont = font_iter->second; return; } LogError("Error trying to load font %s", font); } void ViewBase::SetFontJustification (FontJustification justification) { if (justification == FontJustificationRight) mCurrentFont->setHorizontalJustification(OGLFT::Face::RIGHT); else if (justification == FontJustificationCenter) mCurrentFont->setHorizontalJustification(OGLFT::Face::CENTER); else mCurrentFont->setHorizontalJustification(OGLFT::Face::LEFT); } void ViewBase::SetFontColor (float r, float g, float b) { assert (mCurrentFont); mCurrentFont->setForegroundColor(r, g, b); }; void ViewBase::DrawGLString (float x, float y, const char* str) { glPixelStorei (GL_UNPACK_ALIGNMENT, 1); mCurrentFont->draw (x, y, str); } void ViewBase::DrawGLStringMeasure (const char* str, float *width, float *height) { OGLFT::BBox bbox = mCurrentFont->measure (str); *width = bbox.x_max_ - bbox.x_min_; *height = bbox.y_max_ - bbox.y_min_; } void ViewBase::GetCamereEye (float *eye_out) { assert (mCamera); mCamera->GetEye (eye_out); } void ViewBase::DrawGrid () { float xmin, xmax, xstep, zmin, zmax, zstep; int i, count_x, count_z; xmin = -mGridSizeX; xmax = mGridSizeX; zmin = -mGridSizeZ; zmax = mGridSizeZ; count_x = mGridSizeX * 2; count_z = mGridSizeZ * 2; xstep = 1.; zstep = 1.; glColor3f (1., 1., 1.); glBegin (GL_LINES); for (i = 0; i <= count_x; i++) { glVertex3f (i * xstep + xmin, 0., zmin); glVertex3f (i * xstep + xmin, 0., zmax); } for (i = 0; i <= count_z; i++) { glVertex3f (xmin, 0, i * zstep + zmin); glVertex3f (xmax, 0, i * zstep + zmin); } glEnd (); } void ViewBase::DrawWorld () { } void ViewBase::Resize (int width, int height) { if (height == 0) height = 1; mWindowWidth = static_cast (width); mWindowHeight = static_cast (height); glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(mCamera->GetFOVY (), float (width) / float (height), 0.1, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity (); LogDebug ("Resize to: %d x %d", mWindowWidth,mWindowHeight); /** \warning * This call has to be made for SDL 1.2 for 1.3 there seems to be a * workaround, however since I do not yet run SDL 1.3 I hold on to this. * See http://lists.libsdl.org/pipermail/sdl-libsdl.org/2008-November/067306.html */ if( SDL_SetVideoMode( mWindowWidth, mWindowHeight, 16, SDL_OPENGL | SDL_RESIZABLE ) == 0 ) { LogError ("Video mode set failed: %s", SDL_GetError ()); exit (-1); } } /* bool ViewBase::SendKeyDown (const SDL_keysym &keysym) { std::vector::iterator overlay_iter; for (overlay_iter = mOverlays.begin(); overlay_iter != mOverlays.end(); overlay_iter++) { if ( (*overlay_iter)->OnKeyDown (keysym)) return true; } return false; } bool ViewBase::SendKeyUp (const SDL_keysym &keysym) { std::vector::iterator overlay_iter; for (overlay_iter = mOverlays.begin(); overlay_iter != mOverlays.end(); overlay_iter++) { if ( (*overlay_iter)->OnKeyUp (keysym)) return true; } return false; } bool ViewBase::SendMouseButtonUp (Uint8 button, Uint16 xpos, Uint16 ypos) { std::vector::iterator overlay_iter; for (overlay_iter = mOverlays.begin(); overlay_iter != mOverlays.end(); overlay_iter++) { if ( (*overlay_iter)->OnMouseButtonUp (button, xpos, ypos)) return true; } return false; } bool ViewBase::SendMouseButtonDown (Uint8 button, Uint16 xpos, Uint16 ypos) { std::vector::iterator overlay_iter; for (overlay_iter = mOverlays.begin(); overlay_iter != mOverlays.end(); overlay_iter++) { if ( (*overlay_iter)->OnMouseButtonDown (button, xpos, ypos)) return true; } return false; } */ /* * Global functions */ void DrawGLString (float x, float y, const char* str) { if (!ViewInstance) { LogError ("Cannot Draw GL String: View not yet initialized!"); return; } ViewInstance->DrawGLString (x, y, str); } void SelectFont (const char* font) { if (!ViewInstance) { LogError ("Cannot select font: View not yet initialized!"); return; } ViewInstance->SelectFont(font); } void SetFontJustification (FontJustification justification) { if (!ViewInstance) { LogError ("Cannot select font: View not yet initialized!"); return; } ViewInstance->SetFontJustification (justification); } unsigned int GetWindowWidth() { return ViewInstance->GetWindowWidth (); } unsigned int GetWindowHeight() { return ViewInstance->GetWindowHeight (); } int GetFrameRate () { return ViewInstance->GetFrameRate (); } }