/* 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 "client/client.h" #include "client/shipdrawer.h" #include "client/stardrawer.h" #include "render/render.h" #include "game/game.h" #include "sys/sys.h" #include "math/mathlib.h" #include #include #include #include using namespace render; namespace client { ShipDrawer *shipdrawer = 0; StarDrawer *stardrawer = 0; game::Ship *target = 0; // the view's target void View::init() { // draw scene if (!shipdrawer) { stardrawer = new StarDrawer(&game.star); shipdrawer = new ShipDrawer(&game.ship); target = &game.ship; } } void View::shutdown() { delete stardrawer; stardrawer = 0; delete shipdrawer; shipdrawer = 0; } void View::reset() { // shading model: Gouraud (smooth). gl::shademodel(GL_SMOOTH); // culling gl::cullface(GL_BACK); gl::frontface(GL_CCW); // alpha-blending gl::blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl::disable(GL_BLEND); // depth gl::depthmask(GL_TRUE); gl::disable(GL_DEPTH_TEST); gl::disable(GL_CULL_FACE); } void View::draw_world(float elapsed) { // draw the world gl::push(); gl::translate(game.ship.location - target->location); gl::scale(0.2f, 0.2f, 0.2f); shipdrawer->draw(elapsed); gl::pop(); gl::push(); gl::translate(game.star.location - target->location); stardrawer->draw(elapsed); gl::pop(); } void View::draw_background(float elapsed) { using namespace gl; // galactic axis begin(Lines); color(0.9f, 0.5f, 0.0f); vertex(-2,0,0); color(1.0f, 1.0f, 0.0f); vertex(2,0,0); vertex(0,0,-0.5); vertex(0,0,0.5); vertex(0,1.0f,0); vertex(0,-1, 0); end(); int gridsize = 32; float s = 1.0f / gridsize; float y = -4.0f; float dx = target->location.x - floorf(target->location.x); float dz = target->location.z - floorf(target->location.z); color(0,0, 1.0f); begin(Lines); for (int i=-gridsize; i <= gridsize; i++) { color(0,0, 0, 0); vertex(i-dx, y, -gridsize-dz); color(0,0, (gridsize-abs(i))*s, (gridsize-abs(i))*s); vertex(i-dx, y, -dz); vertex(i-dx, y, -dz); color(0,0, 0, 0); vertex(i-dx, y, gridsize-dz); vertex(-gridsize-dx, y, i-dz); color(0,0, (gridsize-abs(i))*s, (gridsize-abs(i))*s); vertex(-dx, y, i-dz); vertex(-dx, y, i-dz); color(0,0, 0, 0); vertex(gridsize-dx, y, i-dz); } end(); } void View::draw_loader() { gl::enable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, render::textures[0]); // bitmaps/loader.tga gl::color(1.0f, 1.0f, 1.0f, 1.0f); 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(); gl::disable(GL_TEXTURE_2D); } void View::draw_status() { using namespace std; if (console.visible()) return; glBindTexture(GL_TEXTURE_2D, render::textures[1]); // bitmaps/conchars.tga gl::enable(GL_TEXTURE_2D); // print the status in the upper left corner gl::color(1.0f, 1.0f, 1.0f, 1.0f); std::stringstream status; int hours = (int) sys::time() / 3600; int minutes = (int)(sys::time() - 3600*hours) / 60; int seconds = (int)(sys::time() - 3600*hours - 60 *minutes); status << " clock " << setfill('0') << setw(2) << hours << ":" << setfill('0') << setw(2) << minutes << ":" << setfill('0') << setw(2) << seconds; minutes = (int) floorf(core::time() / 60.0f); seconds = (int) floorf(core::time() - (float) minutes* 60.0f); status << " time " << setfill('0') << setw(2) << minutes << ":" << setfill('0') << setw(2) << seconds; status << " fps " << setw(4) << client::fps(); draw_text(0, 4, status); // print the version number in the upper right corner gl::color(0.0f, 1.0f, 0.0f, 1.0f); std::string version("ver. "); version.append(VERSION); draw_text(video.width-(version.size()+1)*CHARWIDTH, 4, version); gl::disable(GL_TEXTURE_2D); } void View::frame(float seconds) { // Clear the color and depth buffers. gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (core::connected()) { // draw the game world // Change to the projection matrix and set our viewing volume. gl::matrixmode(GL_PROJECTION); gl::loadidentity(); const float frustumsize = 0.5f; x = -frustumsize * video.ratio; width = video.ratio; y = -frustumsize; height = 1; gl::frustum(x, x+width, y, y +height, 1.0f, 1024.0f); gl::matrixmode(GL_MODELVIEW); gl::loadidentity(); gl::rotate(90.0f, 0, 1.0, 0); // Camera transformation camera.draw(seconds); gl::enable(GL_DEPTH_TEST); // enable depth buffer writing gl::enable(GL_CULL_FACE); // enable culling draw_world(seconds); // draw the world gl::disable(GL_CULL_FACE); // disable culling gl::enable(GL_BLEND); // enable alpha blending draw_background(seconds); // draw the spacegrid gl::disable(GL_DEPTH_TEST); // disable depth buffer writing } // switch to ortographic projection to draw the GUI gl::matrixmode(GL_PROJECTION); gl::loadidentity(); glOrtho(0, video.width, video.height, 0, -1000.0f, 1000.0f); gl::matrixmode(GL_MODELVIEW); gl::loadidentity(); if (!core::connected()) { // draw the loader bitmap draw_loader(); gl::enable(GL_BLEND); // enable alpha blending } // draw the console console.draw(); // draw the status line draw_status(); gl::disable(GL_BLEND); } } // namespace view