Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2009-01-10 15:36:15 +0000
committerStijn Buys <ingar@osirion.org>2009-01-10 15:36:15 +0000
commit272d229094309bc5875287a5063f818c58c5f4f8 (patch)
treefb9a84748c0a88bfa0e59f63be51455fc239becc /src/client/hud.cc
parent44500292f5a964036e9d915a38a2773bf5aa765d (diff)
hud widget, drawing code reorganization
Diffstat (limited to 'src/client/hud.cc')
-rw-r--r--src/client/hud.cc371
1 files changed, 371 insertions, 0 deletions
diff --git a/src/client/hud.cc b/src/client/hud.cc
new file mode 100644
index 0000000..1eb2591
--- /dev/null
+++ b/src/client/hud.cc
@@ -0,0 +1,371 @@
+/*
+ client/hud.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 "core/core.h"
+#include "client/hud.h"
+#include "client/input.h"
+#include "client/targets.h"
+#include "render/render.h"
+#include "render/renderext.h"
+
+namespace client
+{
+
+HUD::HUD(ui::Widget *parent) : Widget(parent)
+{
+ set_label("hud");
+ set_border(false);
+ set_background(false);
+
+ /*hud_toolbar = new ui::Toolbar(this);
+
+ hud_toolbar->add_button("", "Menu", "ui_menu");
+ hud_toolbar->add_button("", "Chat", "ui_chat");
+ hud_toolbar->add_button("", "Map", "ui_map");
+ */
+ hud_center = new ui::Bitmap(this, "pointers/center");
+ hud_center->set_color(palette()->pointer());
+
+}
+
+void HUD::resize()
+{
+ //hud_toolbar->set_geometry(0.0f, 0.0f, width(), font()->height() *2 );
+
+ hud_center->set_size(ui::pointer_size, ui::pointer_size);
+ hud_center->set_location((size() - hud_center->size()) * 0.5f);
+}
+
+void HUD::draw_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(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 HUD::draw_target(core::Entity *entity, bool is_active_target)
+{
+ using math::Vector3f;
+
+ // don't draw target if we're very close to it
+ if (render::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_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_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(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 HUD::draw()
+{
+ using namespace render;
+ std::stringstream status;
+
+ if (core::localcontrol() && (input::mouse_control || input::joystick_control) &&
+ (render::Camera::mode() == render::Camera::Cockpit || render::Camera::mode() == render::Camera::Track)) {
+ hud_center->set_visible(true);
+ } else {
+ hud_center->set_visible(false);
+ }
+
+ gl::enable(GL_TEXTURE_2D);
+ Text::setfont("gui", 12, 18);
+ Text::setcolor('N'); //set normal color
+
+ // 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_target(entity, true);
+ } else if (entity == targets::current()) {
+ draw_target(entity, true);
+ } else if (entity->type() == core::Entity::Controlable) {
+ draw_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
+ }
+
+ gl::disable(GL_TEXTURE_2D);
+}
+
+}