/* view.cc This file is part of the Osirion project and is distributed under the terms and conditions of the GNU General Public License version 2 */ #include #include #include #include #include #include "client/client.h" #include "client/chat.h" #include "client/console.h" #include "client/input.h" #include "client/targets.h" #include "client/video.h" #include "render/draw.h" #include "render/render.h" #include "render/textures.h" #include "render/camera.h" #include "core/core.h" #include "core/stats.h" #include "math/mathlib.h" #include "sys/sys.h" namespace client { core::Cvar *draw_ui = 0; core::Cvar *draw_stats = 0; core::Cvar *draw_location = 0; core::Cvar *ui_pointercolor = 0; core::Cvar *ui_pointerhovercolor =0; namespace view { float fps = 0; void init() { draw_stats = core::Cvar::get("draw_stats", "0", core::Cvar::Archive); draw_stats->set_info("[bool] draw network and render statistics"); draw_location = core::Cvar::get("draw_location", "0", core::Cvar::Archive); draw_location->set_info("[bool] draw world location"); draw_ui = core::Cvar::get("draw_ui", "1", core::Cvar::Archive); draw_ui->set_info("[bool] draw the user interface"); ui_pointercolor = core::Cvar::get("ui_pointercolor", "0 .5 0", core::Cvar::Archive); ui_pointercolor->set_info("[r g b] mouse pointer color"); ui_pointerhovercolor = core::Cvar::get("ui_pointerhovercolor", "0 1 0", core::Cvar::Archive); ui_pointerhovercolor->set_info("[r g b] mouse pointer hover color"); targets::init(); } void shutdown() { targets::shutdown(); } void draw_loader() { using namespace render; render::Textures::bind("bitmaps/loader"); gl::begin(gl::Quads); glTexCoord2f(0.0f, 0.0f); gl::vertex(0,0, 0); glTexCoord2f(1.0f, 0.0f); gl::vertex(video::width,0,0); glTexCoord2f(1.0f, 1.0f); gl::vertex(video::width,video::height,0); glTexCoord2f(0.0f, 1.0f); gl::vertex(0,video::height,0); gl::end(); } void draw_status() { using namespace render; // print the status in the upper left corner std::stringstream status; if (core::game()) { int minutes = (int) floorf(core::game()->clientframetime() / 60.0f); int seconds = (int) floorf( core::game()->clientframetime() - (float) minutes* 60.0f); status << "^Ntime ^B" << std::setfill(' ') << std::setw(3) << minutes << ":" << std::setfill('0') << std::setw(2) << seconds; Text::draw(video::width-Text::fontwidth()*11-4, 4+Text::fontheight(), status); } // print stats if desired if (draw_stats && draw_stats->value()) { std::stringstream stats; stats << "^Nfps ^B" << std::setw(6) << fps << "\n"; if (core::application()->connected()) { stats << "^Ntris ^B" << std::setw(5) << render::Stats::tris << "\n"; stats << "^Nquads ^B" << std::setw(5) << render::Stats::quads << "\n"; } stats << "^Ntx ^B"<< std::setw(5) << (core::Stats::network_bytes_sent >> 10) << "\n"; stats << "^Nrx ^B"<< std::setw(5) << (core::Stats::network_bytes_received >> 10) << "\n"; Text::draw(video::width-Text::fontwidth()*11-4, 4 + Text::fontheight()*3, stats); } // draw a basic HUD if (core::localcontrol()) { status.str(""); status << "^Nthrust ^B" << std::setfill(' ') << std::setw(5) << std::fixed << std::setprecision(2) << core::localcontrol()->thrust() << " "; status << "^Nspeed ^B" << std::setfill(' ') << std::setw(5) << std::fixed << std::setprecision(2) << core::localcontrol()->speed(); Text::draw(4, video::height - Text::fontheight() -4, status); if (draw_location->value()) { std::stringstream location; location << "^Nloc ^B" << std::fixed << std::setprecision(2) << std::setfill(' ') << std::setw(7) << core::localcontrol()->location().x << " " << std::setw(7) << core::localcontrol()->location().y << " " << std::setw(7) << core::localcontrol()->location().z; Text::draw(4, video::height - Text::fontheight()*2 -4, location); } core::Entity *entity = targets::current(); if (entity) { std::stringstream target; target << "^B" << entity->name() << "\n"; target << "^Ndist ^B"; math::Vector3f v = entity->state()->location() - core::localcontrol()->state()->location(); float d = v.length() - entity->radius() - core::localcontrol()->radius(); if (d > 0 ) target << std::fixed << std::setprecision(2) << std::setfill(' ') << std::setw(8) << d; else target << " --"; Text::draw(video::width - 4-Text::fontwidth()*24, video::height - Text::fontheight()*2 -4, target); } } } void draw_cursor() { if (!core::localcontrol() || console()->visible()) return; float pointer_size = 48.0f; float x = input::mouse_x - (pointer_size /2); float y = input::mouse_y - (pointer_size /2); using namespace render; math::Color color; color.a = 0.5f; if (render::Camera::mode() == render::Camera::Overview) { render::Textures::bind("bitmaps/pointers/aim"); } else { if (!input::mouse_control_override && targets::hover()) { if (ui_pointerhovercolor) { std::stringstream colorstr(ui_pointerhovercolor->str()); colorstr >> color; } render::Textures::bind("bitmaps/pointers/target"); } else if (input::mouse_control) { if (ui_pointercolor) { std::stringstream colorstr(ui_pointercolor->str()); colorstr >> color; } if (render::Camera::mode() == render::Camera::Cockpit || render::Camera::mode() == render::Camera::Track) { render::Textures::bind("bitmaps/pointers/center"); x = (video::width - pointer_size) /2; y = (video::height - pointer_size) /2; gl::color(color); gl::begin(gl::Quads); glTexCoord2f(0,0 ); gl::vertex(x,y,0.0f); glTexCoord2f(1, 0); gl::vertex(x+pointer_size, y, 0.0f); glTexCoord2f(1, 1); gl::vertex(x+pointer_size, y+pointer_size, 0.0f); glTexCoord2f(0, 1); gl::vertex(x, y+pointer_size, 0.0f); gl::end(); } render::Textures::bind("bitmaps/pointers/control"); // if (!input::mouse_deadzone) { x = input::mouse_x - (pointer_size /2); y = input::mouse_y - (pointer_size /2); // } else { // x = (video::width - pointer_size) /2; // y = (video::height - pointer_size) /2; // } } else { render::Textures::bind("bitmaps/pointers/aim"); } } gl::color(color); gl::begin(gl::Quads); glTexCoord2f(0,0 ); gl::vertex(x,y,0.0f); glTexCoord2f(1, 0); gl::vertex(x+pointer_size, y, 0.0f); glTexCoord2f(1, 1); gl::vertex(x+pointer_size, y+pointer_size, 0.0f); glTexCoord2f(0, 1); gl::vertex(x, y+pointer_size, 0.0f); gl::end(); } void reset() { using namespace render; // set clear color gl::clearcolor(0.0f, 0.0f, 0.0f, 1.0f); // load identity matrices gl::matrixmode(GL_MODELVIEW); gl::loadidentity(); gl::matrixmode(GL_MODELVIEW); gl::loadidentity(); // shading model: Gouraud (smooth, the default) gl::shademodel(GL_SMOOTH); //gl::shademodel(GL_FLAT); // lighting settings for the default light GL_LIGHT0 GLfloat light_position[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat ambient_light[] = { 0.01f, 0.01f, 0.01f, 1.0f }; GLfloat diffuse_light[] = { 0.2f, 0.2f, 0.2f, 1.0f }; GLfloat specular_light[] = { 0.2f, 0.2f, 0.2f, 1.0f }; glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_light); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_light); glLightfv(GL_LIGHT0, GL_SPECULAR, specular_light); // GL_LIGHT0 is always enabled gl::enable(GL_LIGHT0); // color tracking glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // material settings GLfloat specular_reflectance[] = { 0.2f, 0.2f, 0.2f, 1.0f }; glMaterialfv(GL_FRONT, GL_SPECULAR, specular_reflectance); glMateriali(GL_FRONT, GL_SHININESS, 128); // shininess 1-128 // alpha blending function gl::blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl::disable(GL_LIGHTING); gl::disable(GL_COLOR_MATERIAL); gl::cullface(GL_BACK); gl::frontface(GL_CCW); gl::disable(GL_CULL_FACE); gl::disable(GL_DEPTH_TEST); gl::disable(GL_BLEND); gl::disable(GL_TEXTURE_2D); } void frame(float seconds) { using namespace render; // calculate frames per second if (seconds > 0.0f) fps = floorf(1.0f / seconds); else fps = 9999; // flush console messages console()->flush(); // Clear the color and depth buffers. gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (core::application()->connected() && core::game()->serverframetime()) { render::draw(seconds); // draw the world targets::draw(); } // switch to ortographic projection to draw the GUI gl::matrixmode(GL_PROJECTION); gl::loadidentity(); glOrtho(0, video::width, video::height, 0, -1024.0f, 1024.0f); gl::matrixmode(GL_MODELVIEW); gl::loadidentity(); gl::enable(GL_TEXTURE_2D); gl::color(1.0f, 1.0f, 1.0f, 1.0f); if (!core::application()->connected()) { // draw the loader bitmap draw_loader(); // force console on if not connected if (!console()->visible()) console()->toggle(); } gl::enable(GL_BLEND); // draw text elements if (draw_ui->value()) { Text::setfont("bitmaps/fonts/gui", 16, 24); // draw the player status draw_status(); // draw the mouse cursor draw_cursor(); } Text::setfont("bitmaps/fonts/console", 12, 18); chat::draw(); console()->draw(); gl::disable(GL_TEXTURE_2D); gl::disable(GL_BLEND); } } //namespace view } // namespace client