diff options
Diffstat (limited to 'src/render')
-rw-r--r-- | src/render/draw.cc | 441 | ||||
-rw-r--r-- | src/render/draw.h | 8 | ||||
-rw-r--r-- | src/render/render.cc | 4 | ||||
-rw-r--r-- | src/render/render.h | 2 | ||||
-rw-r--r-- | src/render/sphere.cc | 9 |
5 files changed, 313 insertions, 151 deletions
diff --git a/src/render/draw.cc b/src/render/draw.cc index 9e1e5ea..77f8457 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -13,6 +13,15 @@ namespace render { +size_t Stats::tris; +size_t Stats::spheres; + +void Stats::clear() +{ + tris = 0; + spheres = 0; +} + Sphere sphere(1); math::Vector3f v0(1, -1, 1); @@ -26,79 +35,19 @@ math::Vector3f v6(-1, 1, -1); math::Vector3f v7(-1, -1, -1); const float drawdistance = 128.0f; +const float drawfxdistance = 32.0f; + math::Vector3f camera_target; float angle = 0; -void draw_model(core::Model *model, core::Entity *entity) -{ - // draw all faces - for (std::list<core::Face *>::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<math::Vector3f *>::iterator vit = (*fit)->face_vertex.begin(); vit != (*fit)->face_vertex.end(); vit++) { - gl::vertex(*(*vit)); - } - gl::end(); - } - - if (r_drawradius && r_drawradius->value()) { - sphere.sphere_color = entity->color(); - sphere.sphere_color.a = 0.25f; - sphere.radius = model->radius(); - gl::enable(GL_BLEND); // enable alpha blending again - sphere.draw(); - gl::disable(GL_BLEND); - } -} - -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<core::Engine *>::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(core::Model *model, core::Entity *entity) -{ - if (model->model_light.size()) { - gl::disable(GL_LIGHTING); - glPointSize(10); - gl::begin(gl::Points); - - for (std::list<core::Light *>::iterator lit = model->model_light.begin(); lit != model->model_light.end(); lit++) { - math::Vector3f location = (*lit)->location(); - gl::color((*lit)->color()); - gl::vertex(location); - } - - gl::end(); - glPointSize(1); - gl::enable(GL_LIGHTING); - } -} +/* ----- Default Entity shapes ------------------------------------- */ void draw_entity_sphere(core::Entity *entity) { sphere.sphere_color = entity->color(); sphere.radius = entity->radius(); sphere.draw(); + Stats::spheres += 1; } void draw_entity_cube(core::Entity *entity) @@ -170,117 +119,311 @@ void draw_entity_axis(core::Entity *entity) gl::end(); } +/* ----- Entity models --------------------------------------------- */ -// draw an entity of entity_type core::Entity::Default -void draw_entity_default(core::Entity *entity) +void draw_model_vertex(core::Model *model, core::Entity *entity) { - using namespace render; + // draw model vertices + if (model->vertex_count()) { + size_t index = model->first_vertex(); + size_t count = model->vertex_count(); - core::Model *model = 0; - if (entity->modelname().size()) { - model = core::Model::get(entity->modelname()); - } + if (r_drawwireframe && r_drawwireframe->value()) { + glDrawArrays(gl::LineLoop, index, count); + } else { + glDrawArrays(gl::Triangles, index, count); + } - if (model && math::distancesquared(camera_target, entity->location()) > drawdistance*drawdistance*model->radius()) - return; + Stats::tris += count/3; + } +} +void draw_model_evertex(core::Model *model, core::Entity *entity) +{ + // draw model evertices + if (model->evertex_count()) { + size_t index = model->first_evertex(); + size_t count = model->evertex_count(); - gl::push(); - gl::translate(entity->location()); - gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); - - if (model) { - draw_model(model, entity); - //draw_model_lights(model, entity); - } else { - if ((entity->flags() & core::Entity::Bright) == core::Entity::Bright) - gl::disable(GL_LIGHTING); - - switch(entity->shape()) { - case core::Entity::Sphere: - draw_entity_sphere(entity); - break; - - case core::Entity::Diamond: + render::gl::color(entity->color()); + glVertexPointer(3, GL_FLOAT, 0, core::VertexArray::evertex); + glNormalPointer(GL_FLOAT, 0, core::VertexArray::evertex_normal); - case core::Entity::Axis: - draw_entity_axis(entity); - break; + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); - case core::Entity::Cube: - - default: - draw_entity_cube(entity); - break; + if (r_drawwireframe && r_drawwireframe->value()) { + glDrawArrays(gl::LineLoop, index, count); + } else { + glDrawArrays(gl::Triangles, index, count); } - if ((entity->flags() & core::Entity::Bright) == core::Entity::Bright) - gl::enable(GL_LIGHTING); + Stats::tris += count/3; } - - gl::pop(); } -// draw an entity of entity_type core::Entity::Controlable -void draw_entity_controlable(core::EntityControlable *entity) +void draw_model_lights(core::Model *model, core::Entity *entity) { - core::Model *model = 0; - if (entity->modelname().size()) - model = core::Model::get(entity->modelname()); + if (model->model_light.size()) { + glPointSize(10); + gl::begin(gl::Points); - gl::push(); - gl::translate(entity->location()); - gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + for (std::list<core::Light *>::iterator lit = model->model_light.begin(); lit != model->model_light.end(); lit++) { + math::Vector3f location = (*lit)->location(); + gl::color((*lit)->color()); + gl::vertex(location); + } + + gl::end(); + glPointSize(1); + } +} - if (model ) { - draw_model(model, entity); - draw_model_engines(model, entity); - //draw_model_lights(model, entity); +void draw_model_engines(core::Model *model, core::EntityControlable *entity) +{ + if (model->model_engine.size() && entity->thrust()) { + gl::color(1.0f, 0.0f ,0.0f, 1.0f); + gl::begin(gl::Lines); + + for (std::list<core::Engine *>::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_radius(core::Model *model, core::Entity *entity) +{ + sphere.sphere_color = entity->color(); + sphere.sphere_color.a = 0.25f; + sphere.radius = model->radius(); + sphere.draw(); + Stats::spheres += 1; +} + +void draw_model_shield(core::Model *model, core::EntityControlable *entity) +{ // shield rotation gl::rotate(angle, 0.0f, 0.0f, 1.0f ); - gl::scale(0.2f, 0.2f, 0.2f); + gl::scale(model->radius(), model->radius(), model->radius()); // draw the shield - gl::color(math::Color(0.0f, 1.0f ,0.0f , 0.5f)); + gl::color(math::Color(0.0f, 1.0f ,0.0f)); gl::begin(gl::LineLoop); - gl::normal(0, 0.5, 0.5); +// gl::normal(0, 0.5, 0.5); gl::vertex(v1); - gl::normal(0, -0.5, 0.5); +// gl::normal(0, -0.5, 0.5); gl::vertex(v0); - gl::normal(0, -0.5, -0.5); +// gl::normal(0, -0.5, -0.5); gl::vertex(v4); - gl::normal(0, 0.5, -0.5); +// gl::normal(0, 0.5, -0.5); gl::vertex(v5); gl::end(); gl::begin(gl::LineLoop); - gl::normal(0, -0.5, 0.5); +// 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::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::normal(0, -0.5, -0.5); gl::vertex(v7); + gl::end(); - gl::pop(); + gl::rotate(-angle, 0.0f, 0.0f, 1.0f ); } +/* ----- Render passes --------------------------------------------- */ -void draw_spacegrid(math::Vector3f const &target) + +inline bool test_draw_distance(core::Model *model, core::Entity *entity) +{ + return (model && (math::distancesquared(camera_target, entity->location()) <= (drawdistance*drawdistance*model->radius()))); +} + +inline bool test_drawfx_distance(core::Model *model, core::Entity *entity) +{ + return (model && (math::distancesquared(camera_target, entity->location()) <= (drawfxdistance*drawfxdistance*model->radius()))); +} + +/* Draw entities without model */ +void draw_pass_default() +{ + std::map<unsigned int, core::Entity *>::iterator it; + for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) { + core::Entity *entity = (*it).second; + + if (!entity->modelname().size()) { + gl::push(); + gl::translate(entity->location()); + gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + + if ((entity->flags() & core::Entity::Bright) == core::Entity::Bright) + gl::disable(GL_LIGHTING); + + 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; + } + + if ((entity->flags() & core::Entity::Bright) == core::Entity::Bright) + gl::enable(GL_LIGHTING); + gl::pop(); + } + } +} + +/* Draw model vertices*/ +void draw_pass_model_vertex() +{ + glVertexPointer(3, GL_FLOAT, 0, core::VertexArray::vertex); + glNormalPointer(GL_FLOAT, 0, core::VertexArray::vertex_normal); + glColorPointer(3, GL_FLOAT, 0, core::VertexArray::vertex_color); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + std::map<unsigned int, core::Entity *>::iterator it; + for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) { + core::Entity *entity = (*it).second; + + core::Model *model = 0; + if (entity->modelname().size()) { + model = core::Model::get(entity->modelname()); + } + + if (test_draw_distance(model, entity)) { + gl::push(); + gl::translate(entity->location()); + gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + + draw_model_vertex(model, entity); + + gl::pop(); + } + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); +} + +/* Draw entites with model evertices */ +void draw_pass_model_evertex() +{ + glVertexPointer(3, GL_FLOAT, 0, core::VertexArray::evertex); + glNormalPointer(GL_FLOAT, 0, core::VertexArray::evertex_normal); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + std::map<unsigned int, core::Entity *>::iterator it; + for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) { + core::Entity *entity = (*it).second; + + core::Model *model = 0; + if (entity->modelname().size()) { + model = core::Model::get(entity->modelname()); + } + + if (test_draw_distance(model, entity)) { + gl::push(); + gl::translate(entity->location()); + gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + + draw_model_evertex(model, entity); + + gl::pop(); + } + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); +} + +/* Draw model lights, engines */ +void draw_pass_model_fx() { + + for (std::map<unsigned int, core::Entity *>::iterator it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) { + core::Entity *entity = (*it).second; + + core::Model *model = 0; + if (entity->modelname().size()) { + model = core::Model::get(entity->modelname()); + } + + if (test_drawfx_distance(model, entity) && (model->model_light.size() || (entity->type() == core::Entity::Controlable))) { + + gl::push(); + gl::translate(entity->location()); + gl::rotate(entity->direction(), 0.0f, 0.0f, 1.0f ); + + draw_model_lights(model, entity); + + if (entity->type() == core::Entity::Controlable) { + draw_model_engines(model, (core::EntityControlable *)entity); + draw_model_shield(model, (core::EntityControlable *)entity); + } + gl::pop(); + } + } +} + +void draw_pass_model_radius() +{ + if (!(r_drawradius && r_drawradius->value())) + return; + + for (std::map<unsigned int, core::Entity *>::iterator it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) { + core::Entity *entity = (*it).second; + core::Model *model = 0; + if (entity->modelname().size()) { + model = core::Model::get(entity->modelname()); + } + + if (test_draw_distance(model, entity)) { + gl::push(); + gl::translate(entity->location()); + + draw_model_radius(model, entity); + + gl::pop(); + } + } + +} + +void draw_pass_spacegrid() { 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); + float dx = camera_target.x - floorf(camera_target.x); + float dy = camera_target.y - floorf(camera_target.y); - gl::translate(target); + gl::push(); + gl::translate(camera_target); gl::color(0,0, 1.0f); gl::normal(0, 0, 1.0f); @@ -302,10 +445,16 @@ void draw_spacegrid(math::Vector3f const &target) gl::vertex(gridsize-dx, i-dy, z); } gl::end(); + + gl::pop(); } +/* ----- Main draw routine ----------------------------------------- */ + void draw(math::Vector3f const &eye, math::Vector3f const &target, float seconds) { + Stats::clear(); + // used for animations angle += 180.0f * seconds; if( angle > 360.0f ) { @@ -313,37 +462,31 @@ void draw(math::Vector3f const &eye, math::Vector3f const &target, float seconds } camera_target = target; - - // 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::disable(GL_BLEND); // disbable alpha blending for world polys - std::map<unsigned int, core::Entity *>::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<core::EntityControlable *> ((*it).second)); - break; - default: - break; - } - } + draw_pass_default(); // draw entities without model + draw_pass_model_vertex(); // draw entities with model + draw_pass_model_evertex(); // draw entities with model, vertices with entity color + + gl::disable(GL_LIGHTING); + gl::enable(GL_BLEND); + + draw_pass_model_fx(); // draw entity lights and engines + + gl::enable(GL_LIGHTING); + + draw_pass_model_radius(); //draw entity radius 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 - draw_spacegrid(target); // draw the blue spacegrid + draw_pass_spacegrid(); // draw the blue spacegrid gl::disable(GL_DEPTH_TEST); // disable depth buffer writing } diff --git a/src/render/draw.h b/src/render/draw.h index 2590be2..f9f35f3 100644 --- a/src/render/draw.h +++ b/src/render/draw.h @@ -15,6 +15,14 @@ namespace render /// draw the world void draw(math::Vector3f const &eye, math::Vector3f const &target, float seconds); +class Stats { +public: + static void clear(); + + static size_t tris; + static size_t spheres; +}; + } #endif // __INCLUDED_RENDER_DRAW_H__ diff --git a/src/render/render.cc b/src/render/render.cc index b5afdf0..b7f42a8 100644 --- a/src/render/render.cc +++ b/src/render/render.cc @@ -14,6 +14,8 @@ namespace render { GLuint textures[32]; core::Cvar *r_drawradius = 0; +core::Cvar *r_drawstats = 0; +core::Cvar *r_drawwireframe = 0; void init() { @@ -35,6 +37,8 @@ void init() } r_drawradius = core::Cvar::get("r_drawradius", "0", core::Cvar::Archive); + r_drawstats = core::Cvar::get("r_drawstats", "0", core::Cvar::Archive); + r_drawwireframe = core::Cvar::get("r_drawwireframe", "0", core::Cvar::Archive); } void shutdown() diff --git a/src/render/render.h b/src/render/render.h index 7d26a3d..c622dfe 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -24,6 +24,8 @@ namespace render { extern GLuint textures[32]; extern core::Cvar *r_drawradius; + extern core::Cvar *r_drawwireframe; + extern core::Cvar *r_drawstats; } #include "render/draw.h" diff --git a/src/render/sphere.cc b/src/render/sphere.cc index 616424e..4a94acd 100644 --- a/src/render/sphere.cc +++ b/src/render/sphere.cc @@ -5,6 +5,7 @@ */ #include "render/sphere.h" +#include "render/render.h" #include "math/mathlib.h" using math::Vector3f; @@ -90,8 +91,12 @@ void Sphere::draw() for (int j=0; j < segments-1; j++) { r = radius*sintable[j]; float r1 = radius*sintable[j+1]; - - begin(QuadStrip); + // draw all vertexes + if (r_drawwireframe && r_drawwireframe->value()) { + gl::begin(gl::LineStrip); + } else { + gl::begin(gl::QuadStrip); + } v = Vector3f(r, radius*costable[j], 0); n = v; n.normalize(); |