/* render/draw.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 "core/model.h" #include "render/draw.h" #include "render/sphere.h" namespace render { render::Sphere sphere(1); math::Vector3f v0(1, -1, 1); math::Vector3f v1(1, 1, 1); math::Vector3f v2(-1, 1, 1); math::Vector3f v3(-1, -1, 1); math::Vector3f v4(1, -1, -1); math::Vector3f v5(1, 1, -1); math::Vector3f v6(-1, 1, -1); math::Vector3f v7(-1, -1, -1); float angle = 0; void draw_model(core::Model *model, core::Entity *entity) { // draw all faces for (std::list::iterator fit = model->model_face.begin(); fit != model->model_face.end(); fit++) { if ((*fit)->color()) { render::gl::color(*(*fit)->color()); } else { render::gl::color(entity->color()); } // draw all vertexes gl::begin(gl::Polygon); //gl::begin(gl::LineLoop); gl::normal((*fit)->normal()); for (std::vector::iterator vit = (*fit)->face_vertex.begin(); vit != (*fit)->face_vertex.end(); vit++) { gl::vertex(*(*vit)); } gl::end(); } } void draw_model_engines(core::Model *model, core::EntityControlable *entity) { if (model->model_engine.size() && entity->thrust()) { gl::color(1.0f,0 ,0); gl::begin(gl::Lines); for (std::list::iterator eit = model->model_engine.begin(); eit != model->model_engine.end(); eit++) { math::Vector3f const & v = (*eit)->location(); gl::vertex(v); gl::vertex(v.x - 0.0625f*entity->thrust(), v.y, v.z); } gl::end(); } } void draw_model_lights(math::Vector3f const & eye, math::Vector3f const & target) { glPointSize(10); gl::begin(gl::Points); std::map::iterator it; for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) { core::Model *model = 0; if ((*it).second->modelname().size()) model = core::Model::get((*it).second->modelname()); if (model) { for (std::list::iterator lit = model->model_light.begin(); lit != model->model_light.end(); lit++) { math::Vector3f location = (*it).second->location() + (*lit)->location(); math::Vector3f d = location-eye; if ((d.lengthsquared() < 16*16) && (dotproduct(d, eye-target) < 0)) { gl::color((*lit)->color()); gl::vertex(location); } } } } gl::end(); glPointSize(1); } void draw_entity_sphere(core::Entity *entity) { sphere.sphere_color = entity->color(); sphere.radius = entity->radius(); sphere.draw(); } void draw_entity_cube(core::Entity *entity) { float radius = entity->radius()/2; gl::scale(radius, radius, radius); gl::color(entity->color()); gl::begin(gl::Quads); // top gl::normal(0,0,1); gl::vertex(v0); gl::vertex(v1); gl::vertex(v2); gl::vertex(v3); // bottom gl::normal(0,0, -1); gl::vertex(v7); gl::vertex(v6); gl::vertex(v5); gl::vertex(v4); // sides gl::normal(1,0,0); gl::vertex(v1); gl::vertex(v0); gl::vertex(v4); gl::vertex(v5); gl::normal(-1,0,0); gl::vertex(v3); gl::vertex(v2); gl::vertex(v6); gl::vertex(v7); gl::normal(0,1,0); gl::vertex(v2); gl::vertex(v1); gl::vertex(v5); gl::vertex(v6); gl::normal(0,-1,0); gl::vertex(v0); gl::vertex(v3); gl::vertex(v7); gl::vertex(v4); gl::end(); } void draw_entity_axis(core::Entity *entity) { using namespace render; float r = entity->radius(); gl::begin(gl::Lines); gl::color(1.0f, 0.0f, 0.0f); gl::vertex(r,0.0f,0.0f); gl::color(entity->color()); gl::vertex(-r,0.0f,0.0f); gl::vertex(0.0f,r/2,0.0f); gl::vertex(0.0f,-r/2,0.0f); gl::vertex(0.0f,0.0f,r); gl::vertex(0.0f,0.0f,-r); gl::end(); } // draw an entity of entity_type core::Entity::Default void draw_entity_default(core::Entity *entity) { using namespace render; core::Model *model = 0; if (entity->modelname().size()) model = core::Model::get(entity->modelname()); gl::push(); gl::translate(entity->location()); gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); if (model) { draw_model(model, entity); } else { //gl::disable(GL_LIGHTING); //gl::disable(GL_LIGHT0); switch(entity->shape()) { case core::Entity::Sphere: draw_entity_sphere(entity); break; case core::Entity::Diamond: case core::Entity::Axis: draw_entity_axis(entity); break; case core::Entity::Cube: default: draw_entity_cube(entity); break; } //gl::enable(GL_LIGHTING); //gl::enable(GL_LIGHT0); // disable camera light } gl::pop(); } // draw an entity of entity_type core::Entity::Controlable void draw_entity_controlable(core::EntityControlable *entity) { core::Model *model = 0; if (entity->modelname().size()) model = core::Model::get(entity->modelname()); gl::push(); gl::translate(entity->location()); gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); if (model) { draw_model(model, entity); draw_model_engines(model, entity); } // shield rotation gl::rotate(angle, 0.0f, 0.0f, 1.0f ); gl::scale(0.2f, 0.2f, 0.2f); // draw the shield gl::color(math::Color(0.0f, 1.0f ,0.0f , 0.5f)); gl::begin(gl::LineLoop); gl::normal(0, 0.5, 0.5); gl::vertex(v1); gl::normal(0, -0.5, 0.5); gl::vertex(v0); gl::normal(0, -0.5, -0.5); gl::vertex(v4); gl::normal(0, 0.5, -0.5); gl::vertex(v5); gl::end(); gl::begin(gl::LineLoop); gl::normal(0, -0.5, 0.5); gl::vertex(v3); gl::normal(0, 0.5, 0.5); gl::vertex(v2); gl::normal(0, 0.5, -0.5); gl::vertex(v6); gl::normal(0, -0.5, -0.5); gl::vertex(v7); gl::end(); gl::pop(); } void draw_spacegrid(math::Vector3f const &target) { int gridsize = 32; float s = 1.0f / gridsize; float z = -4.0f; float dx = target.x - floorf(target.x); float dy = target.y - floorf(target.y); gl::translate(target); gl::color(0,0, 1.0f); gl::normal(0, 0, 1.0f); gl::begin(gl::Lines); for (int i=-gridsize; i <= gridsize; i++) { gl::color(0,0, 0, 0); gl::vertex(i-dx, -gridsize-dy, z); gl::color(0,0, (gridsize-abs(i))*s, (gridsize-abs(i))*s); gl::vertex(i-dx, -dy, z ); gl::vertex(i-dx, -dy ,z ); gl::color(0,0, 0, 0); gl::vertex(i-dx, gridsize-dy, z); gl::vertex(-gridsize-dx, i-dy, z ); gl::color(0,0, (gridsize-abs(i))*s, (gridsize-abs(i))*s); gl::vertex(-dx, i-dy, z); gl::vertex(-dx, i-dy, z); gl::color(0,0, 0, 0); gl::vertex(gridsize-dx, i-dy, z); } gl::end(); } void draw(math::Vector3f const &eye, math::Vector3f const &target, float seconds) { // used for animations angle += 180.0f * seconds; if( angle > 360.0f ) { angle -= 360.0f; } // draw entities using namespace render; gl::enable(GL_DEPTH_TEST); // enable depth buffer writing gl::enable(GL_CULL_FACE); // enable culling gl::enable(GL_COLOR_MATERIAL); // enable color tracking gl::enable(GL_LIGHTING); gl::enable(GL_LIGHT0); gl::disable(GL_BLEND); // disbable alpha blending for world polys std::map::iterator it; for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) { switch ((*it).second->type()) { case core::Entity::Default: draw_entity_default((*it).second); break; case core::Entity::Controlable: draw_entity_controlable(static_cast ((*it).second)); break; default: break; } } gl::disable(GL_LIGHT0); // disable camera light gl::disable(GL_LIGHTING); gl::disable(GL_COLOR_MATERIAL); // disable color tracking gl::disable(GL_CULL_FACE); // disable culling gl::enable(GL_BLEND); // enable alpha blending again /* // DEBUG target lines gl::push(); gl::color(0,1, 0, .7); //gl::translate(target*-1); gl::begin(gl::Lines); for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) { gl::vertex(eye); gl::vertex((*it).second->location()); } gl::end(); gl::pop(); draw_model_lights(eye, target); // second pass - draw lights */ draw_spacegrid(target); // draw the blue spacegrid gl::disable(GL_DEPTH_TEST); // disable depth buffer writing } }