From 272d229094309bc5875287a5063f818c58c5f4f8 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sat, 10 Jan 2009 15:36:15 +0000 Subject: hud widget, drawing code reorganization --- src/client/view.cc | 548 ++--------------------------------------------------- 1 file changed, 12 insertions(+), 536 deletions(-) (limited to 'src/client/view.cc') diff --git a/src/client/view.cc b/src/client/view.cc index 1c1b108..d8346cb 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -29,13 +29,6 @@ namespace client { -core::Cvar *draw_ui = 0; -core::Cvar *draw_stats = 0; -core::Cvar *draw_devinfo = 0; -core::Cvar *draw_keypress = 0; - -unsigned long previousframe = 0; - void time_to_stream(std::stringstream &str, float time) { int minutes = (int) floorf(time / 60.0f); @@ -193,24 +186,14 @@ View::View(ui::Widget *parent) : ui::Widget(parent) set_label("view"); set_border(false); - // initialize client variables - draw_devinfo = core::Cvar::get("draw_devinfo", "0", core::Cvar::Archive); - draw_devinfo->set_info("[bool] draw developer information"); - - draw_stats = core::Cvar::get("draw_stats", "0", core::Cvar::Archive); - draw_stats->set_info("[bool] draw network and render statistics"); - - draw_keypress = core::Cvar::get("draw_keypress", "0", core::Cvar::Archive); - draw_keypress->set_info("[bool] draw keypress key names"); - // add child widgets - view_center = new ui::Bitmap(this, "pointers/center"); view_devinfo = new DevInfo(this); view_stats = new Stats(this); view_keypress = new KeyPress(this); view_notify = new Notifications(this); view_chat = new Chat(this); view_map = new Map(this); + view_hud = new HUD(this); // make sure the view is at the bottom of the draw stack lower(); @@ -220,6 +203,10 @@ void View::resize() { set_size(parent()->size()); + // set hud geometry + view_hud->set_geometry(0,0, width(), height()); + view_hud->event_resize(); + // reposition devinfo widget view_devinfo->set_size(font()->width()*32, font()->height()*5); view_devinfo->set_location(font()->width() * 0.5f, font()->height() * 0.5f); @@ -237,11 +224,6 @@ void View::resize() view_map->set_size(width() - font()->width() * 8, height() - font()->height() * 8); view_map->set_location(font()->width() * 4, font()->height() * 4); - // reposition center - view_center->set_size(ui::pointer_size, ui::pointer_size); - view_center->set_location((size() - view_center->size()) * 0.5f); - view_center->set_color(palette()->pointer()); - // reposition notifications view_notify->set_location(ui::UI::elementsize.width()*2.0f+ font()->width(), view_devinfo->top() + view_devinfo->height() + font()->height()); view_notify->set_size(width() - ui::UI::elementsize.width()*2.0f - font()->width() * 2, height() * 0.5f - view_notify->top()); @@ -249,6 +231,13 @@ void View::resize() void View::draw() { + // draw hud only when connected and controlling a spacecraft + if (core::application()->connected() && core::localcontrol() && !ui::root()->active()) { + view_hud->set_visible(true); + } else { + view_hud->set_visible(false); + } + // reposition chat widget if (!view_chat->small_view()) { view_chat->set_location(font()->width(), view_devinfo->top() + view_devinfo->height() + font()->height()); @@ -279,520 +268,7 @@ void View::draw() if (!core::localcontrol()) { view_map->set_visible(false); } - - if (core::localcontrol() && (input::mouse_control || input::joystick_control) && - (render::Camera::mode() == render::Camera::Cockpit || render::Camera::mode() == render::Camera::Track)) { - view_center->set_visible(true); - } else { - view_center->set_visible(false); - } -} - -/* -- namespace view ----------------------------------------------- */ - -namespace view -{ - -void init() -{ - // FIXME integrate with libui - draw_ui = core::Cvar::get("draw_ui", "1", core::Cvar::Archive); - draw_ui->set_info("[bool] draw the user interface"); - - targets::init(); - - previousframe = 0; -} - -void shutdown() -{ - targets::shutdown(); -} - -/* - FIXME should be merged with the render passes - and in the bbox pass -*/ - -void draw_entity_world_target(core::Entity *entity) -{ - model::Model *model = entity->model(); - if (!model) - return; - - if (!model->docks().size()) - return; - - float d = math::distance(core::localcontrol()->location(), entity->location()) - entity->radius() - core::localcontrol()->radius(); - if (d > 100.0f) - return; - - gl::enable(GL_DEPTH_TEST); - gl::push(); - gl::translate(entity->location()); - gl::multmatrix(entity->axis()); - - gl::color(0, 1.0f, 1.0f, 1.0f); - - for (model::Model::Docks::iterator dit = model->docks().begin(); dit != model->docks().end(); dit++) { - model::Dock *dock = (*dit); - math::Vector3f maxbox(dock->location()); - math::Vector3f minbox(dock->location()); - - for (size_t i=0; i < 3; i++) { - maxbox[i] += 0.025; - minbox[i] -= 0.025; - } - - // top - gl::begin(gl::LineLoop); - gl::vertex(maxbox.x, maxbox.y, maxbox.z); - gl::vertex(minbox.x, maxbox.y, maxbox.z); - gl::vertex(minbox.x, minbox.y, maxbox.z); - gl::vertex(maxbox.x, minbox.y, maxbox.z); - gl::end(); - - // bottom - gl::begin(gl::LineLoop); - gl::vertex(maxbox.x, maxbox.y, minbox.z); - gl::vertex(minbox.x, maxbox.y, minbox.z); - gl::vertex(minbox.x, minbox.y, minbox.z); - gl::vertex(maxbox.x, minbox.y, minbox.z); - gl::end(); - - gl::begin(gl::Lines); - gl::vertex(maxbox.x, maxbox.y, maxbox.z); - gl::vertex(maxbox.x, maxbox.y, minbox.z); - gl::vertex(minbox.x, maxbox.y, maxbox.z); - gl::vertex(minbox.x, maxbox.y, minbox.z); - gl::vertex(minbox.x, minbox.y, maxbox.z); - gl::vertex(minbox.x, minbox.y, minbox.z); - gl::vertex(maxbox.x, minbox.y, maxbox.z); - gl::vertex(maxbox.x, minbox.y, minbox.z); - gl::end(); - } - - gl::pop(); - gl::disable(GL_DEPTH_TEST); - -} - -void draw_entity_offscreen_target(core::Entity *entity, bool is_active_target) -{ - - math::Vector3f target(entity->location() - render::Camera::eye()); - target = render::Camera::axis().transpose() * target; - - float cx = 0; - float cy = 0; - - if ( target.y*target.y + target.z*target.z < 0.0001 ) { - // X - bound, behind (front is visible) - cx = 0.0f; - cy = -0.5f; - - } else if (fabs(target.y) > fabs(target.z)) { - // Y-bound - cx = math::sgnf(target.y) * 0.5f; - cy = 0.5f * target.z / fabs(target.y); - } else { - // Z-bound - cx = 0.5f * target.y / fabs(target.z); - cy = math::sgnf(target.z) * 0.5f; - } - - const float r = 16; - const float margin = 24; - cx = (0.5f - cx) * ((float) render::State::width() - margin*2); - cx += margin; - cy = (0.5f - cy) * ((float) render::State::height() - margin*2); - cy += margin; - - gl::disable(GL_TEXTURE_2D); - gl::color(0, 0, 0, 1); - gl::begin(gl::LineLoop); - glVertex3f(cx+r, cy+2, 0); - glVertex3f(cx, cy+r+2, 0); - glVertex3f(cx-r, cy+2, 0); - glVertex3f(cx, cy-r+2, 0); - gl::end(); - - if (entity == core::localplayer()->mission_target()) { - gl::color(ui::root()->palette()->mission()); - } else if (entity->type() == core::Entity::Controlable) { - gl::color(0, 1, 0, 1); // FIXME allegiance color - } else { - gl::color(1, 1, 1, 1); // FIXME neutral color - } - - gl::begin(gl::LineLoop); - glVertex3f(cx+r, cy, 0); - glVertex3f(cx, cy+r, 0); - glVertex3f(cx-r, cy, 0); - glVertex3f(cx, cy-r, 0); - gl::end(); - gl::enable(GL_TEXTURE_2D); -} - -void draw_entity_target(core::Entity *entity, bool is_active_target) -{ - using math::Vector3f; - - // don't draw target if we're very close to it - if (ext_render(entity)->distance() < 0.001f) - return; - - // don't draw target if it is outside the visible cone - Vector3f target(entity->location() - render::Camera::eye()); - if (math::dotproduct(render::Camera::axis().forward(), Vector3f::normalized(target)) < 0.75 ) { - draw_entity_offscreen_target(entity, is_active_target); - return; - } - - // transform the target into the camera coordinate system - target = render::Camera::axis().transpose() * target; - - // calculate the intersection between the line (0,0,0)-target and the frustum front - float t = (render::Camera::frustum_front() + 0.001f) / target.x; - Vector3f center(target *t); - - float cx = render::State::width() * (0.5 - center.y); - float cy = render::State::height() * (0.5 - center.z * render::State::aspect()); - - if ((cx < 0 ) || (cy < 0) || (cx > render::State::width()) || (cy > render::State::height())) { - draw_entity_offscreen_target(entity, is_active_target); - return; - } - - float r = ui::pointer_size; - if (!is_active_target) - r *= 0.5; - - gl::disable(GL_TEXTURE_2D); - // outer square shadow - gl::color(0, 0, 0, 1); - gl::begin(gl::LineLoop); - gl::vertex(cx+r, cy+2); - gl::vertex(cx, cy+r+2); - gl::vertex(cx-r, cy+2); - gl::vertex(cx, cy-r+2); - gl::end(); - - if ((entity->flags() & core::Entity::Dockable) == core::Entity::Dockable) { - gl::begin(gl::LineLoop); - gl::vertex(cx+ (r*0.25f), cy+2); - gl::vertex(cx, cy+(r*0.25f)+2); - gl::vertex(cx-(r*0.25f), cy+2); - gl::vertex(cx, cy-(r*0.25f)+2); - gl::end(); - } - - if (entity == core::localplayer()->mission_target()) { - gl::color(ui::root()->palette()->mission()); - } else if (entity->type() == core::Entity::Controlable) { - gl::color(0, 1, 0, 1); // FIXME allegiance color - } else { - gl::color(1, 1, 1, 1); // FIXME neutral color - } - - // outer square0 - gl::begin(gl::LineLoop); - gl::vertex(cx+r, cy); - gl::vertex(cx, cy+r); - gl::vertex(cx-r, cy); - gl::vertex(cx, cy-r); - gl::end(); - - if ((entity->flags() & core::Entity::Dockable) == core::Entity::Dockable) { - gl::begin(gl::LineLoop); - gl::vertex(cx+(r*0.25f), cy); - gl::vertex(cx, cy+(r*0.25f)); - gl::vertex(cx-(r*0.25f), cy); - gl::vertex(cx, cy-(r*0.25f)); - gl::end(); - } - - gl::enable(GL_TEXTURE_2D); - - if (is_active_target) { - // entity name and distance - std::stringstream strdistance; - float d = math::distance(core::localcontrol()->location(), entity->location()) - entity->radius() - core::localcontrol()->radius(); - if (d > 0 ) { - if (d > 100.0f) { - strdistance << roundf(d * 0.1f) << "km"; - } else { - strdistance << roundf(d * 100.0f) << "m"; - } - } else { - strdistance << "--"; - } - if (entity->type() == core::Entity::Controlable) { - render::Text::setcolor('B'); - } else { - render::Text::setcolor('N'); - } - render::Text::draw(cx-aux::text_length(entity->name()) * render::Text::fontwidth()*0.5f, - cy-r-4-render::Text::fontheight(), entity->name()); - - render::Text::draw(cx - aux::text_length(strdistance.str()) * render::Text::fontwidth() * 0.5f, - cy+r+4, strdistance); - } -} - -void draw_hud() -{ - using namespace render; - std::stringstream status; - - // draw a basic HUD - if(core::localplayer()->view()) { - Text::setcolor('N'); //set normal color - Text::draw(render::State::width()-4-Text::fontwidth()*32, render::State::height()-Text::fontheight()*3-4, core::localcontrol()->zone()->name()); - - Text::setcolor('B'); //set bold color - Text::draw(render::State::width() - 4-Text::fontwidth()*32, render::State::height() - Text::fontheight()*2 -4, core::localplayer()->view()->name()); - - } else if (core::localcontrol() && core::localcontrol()->zone()) { - core::Zone *zone = core::localcontrol()->zone(); - - // draw targets - for (core::Zone::Content::iterator it=zone->content().begin(); it != zone->content().end(); it++) { - core::Entity *entity = (*it); - - if (targets::is_legal_target(entity)) { - if (entity == core::localplayer()->mission_target()) { - draw_entity_target(entity, true); - } else if (entity == targets::current()) { - draw_entity_target(entity, true); - } else if (entity->type() == core::Entity::Controlable) { - draw_entity_target(entity, false); - } - } - } - - unsigned int state = core::localcontrol()->eventstate(); - if (state) { - std::stringstream statestr; - statestr.clear(); - if (state == core::Entity::ImpulseInitiate) { - statestr << "^FInitializing kinetic impulse drive " << core::localcontrol()->timer(); - } else if (state == core::Entity::Impulse) { - //statestr << "^FKinetic impulse"; - } else if (state == core::Entity::JumpInitiate) { - statestr << "^FInitializing hyperspace jump drive "<< core::localcontrol()->timer(); - } else if (state == core::Entity::Jump) { - statestr << "^FJumping..."; - } - - Text::draw(4, render::State::height() - Text::fontheight()*3-4, statestr); - } - - core::Entity *target = targets::current(); - std::stringstream strdistance; - float d = 0; - float y = 1.0f; - - if (target) { - std::stringstream strtarget; - strtarget << "^B" << target->name() << "\n^B"; - - d = math::distance(core::localcontrol()->location(), target->location()) - - target->radius() - core::localcontrol()->radius(); - - if (d > 0 ) { - strtarget << "^Ndist:^B "; - if (d > 100.0f) { - strtarget << roundf(d * 0.1f) << "km"; - } else { - strtarget << roundf(d * 100.0f) << "m"; - } - - if (core::localcontrol()->speed() > 0.1f) { - strtarget << "^N eta:^B "; - float eta = floorf(d / core::localcontrol()->speed() ); - if (eta > 60.0f) { - float etamin = floorf(eta / 60.0f); - strtarget << etamin << "min "; - eta -= etamin * 60; - } - strtarget << eta << "sec"; - } - } else { - strtarget << " --"; - } - strtarget << '\n'; - Text::draw(render::State::width() - 4-Text::fontwidth()*32, render::State::height() - Text::fontheight()*2 -4, strtarget); - y += 2.0f; - } - - Text::setcolor('N'); //set normal color - Text::draw(render::State::width()-4-Text::fontwidth()*32, render::State::height()-Text::fontheight()*y-4, core::localcontrol()->zone()->name()); - - Textures::bind("bitmaps/hud/thruster_base"); // 316 x 32 bitmap - gl::color(1, 1, 1, 1); - gl::begin(gl::Quads); - - glTexCoord2f(0, 0); - gl::vertex(4, render::State::height() - 4 - 32, 0); - - glTexCoord2f(1, 0); - gl::vertex(4 + 316, render::State::height() - 4 - 32, 0); - - glTexCoord2f(1, 1); - gl::vertex(4 + 316, render::State::height() - 4 , 0); - - glTexCoord2f(0, 1); - gl::vertex(4, render::State::height() - 4 , 0); - - gl::end(); - - float u = core::localcontrol()->thrust(); - if (core::localcontrol()->eventstate() == core::Entity::Impulse) { - u = 1.0; - } - - if (( u > 0) || (core::localcontrol()->eventstate() == core::Entity::Impulse)) { - - if (core::localcontrol()->eventstate() == core::Entity::Impulse) { - gl::color(0, .8, 0); - } else { - float d = math::absf(input::local_thrust - u); - if (d > 0.1) { - d = 0.1f; - } - gl::color(1, 1, .5f + d * 5.0f); - } - Textures::bind("bitmaps/hud/thruster_indicator"); // 316 x 32 bitmap - gl::begin(gl::Quads); - glTexCoord2f(0, 0); - gl::vertex(4, render::State::height() - 4 - 32, 0); - - glTexCoord2f(u, 0); - gl::vertex(4.0f + u * 316.0f, render::State::height() - 4 - 32, 0); - - glTexCoord2f(u, 1); - gl::vertex(4.0f + u * 316.0f, render::State::height() - 4 , 0); - - glTexCoord2f(0, 1); - gl::vertex(4, render::State::height() - 4 , 0); - - gl::end(); - } - - Text::setfont("gui", 14, 24); - Text::setcolor('B'); //set normal color - - std::stringstream speedstr; - speedstr << "^B" << roundf(core::localcontrol()->speed() * 100.0f); - Text::draw( 316+4+10, render::State::height() - 6 -16 - render::Text::fontwidth() /2, speedstr); - - Text::setfont("gui", 12, 18); - Text::setcolor('N'); //set normal color - } -} - -void set_cursor() -{ - if (ui::console()->visible()) { - ui::root()->set_pointer(); - - } else if(core::localplayer()->view() || ui::root()->active()) { - - ui::root()->set_pointer("pointer"); - - } else if (!core::localcontrol()) { - - ui::root()->set_pointer(); - - } else if (client()->view()->map()->hover()) { - - ui::root()->set_pointer("pointer"); - - } else if (render::Camera::mode() == render::Camera::Overview) { - - ui::root()->set_pointer("aim"); - - } else if (targets::hover()) { - - ui::root()->set_pointer("target", ui::Palette::Active, true); - - if (input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) { - ui::root()->input_mouse(render::State::width()/2, render::State::height() /2); - } - - } else if (input::mouse_control) { - - ui::root()->set_pointer("control", ui::Palette::Pointer); - - if (input::mouse_deadzone) { - ui::root()->input_mouse(render::State::width()/2, render::State::height() /2); - } - - } else if ((input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) && - (render::Camera::mode() == render::Camera::Cockpit || render::Camera::mode() == render::Camera::Track)) { - - ui::root()->set_pointer(); - - } else { - - ui::root()->set_pointer("aim", ui::Palette::Foreground); - } } -void frame(float elapsed) -{ - using namespace render; - - // Clear the color and depth buffers. - gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - render::Stats::clear(); - - if (core::application()->connected() && core::game()->time() && core::localplayer()->zone()) { - render::Camera::frame(elapsed); - render::Camera::frustum(); - - render::draw(elapsed); // draw the world - targets::frame(); // validate current target, render sound - - if (!core::localplayer()->view() && targets::current()) // draw target docks etc - draw_entity_world_target(targets::current()); - - render::Camera::ortho(); - - } else { - render::Camera::ortho(); - } - - gl::color(1.0f, 1.0f, 1.0f, 1.0f); - gl::disable(GL_TEXTURE_2D); - gl::enable(GL_BLEND); - - // draw the user interface - if (draw_ui->value()) { - // draw the hud - TODO move as much as possible into ui:: - if (draw_ui->value() && !ui::root()->active()) { - gl::enable(GL_TEXTURE_2D); - gl::color(1.0f, 1.0f, 1.0f, 1.0f); - Text::setfont("gui", 12, 18); - - // draw the hud - draw_hud(); - } - - set_cursor(); - ui::root()->frame(); - - } else if (ui::console()->visible()) { - ui::console()->event_draw(); - } - - gl::disable(GL_TEXTURE_2D); - gl::disable(GL_BLEND); -} - -} //namespace view - } // namespace client -- cgit v1.2.3