Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/draw.cc')
-rw-r--r--src/render/draw.cc441
1 files changed, 292 insertions, 149 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
}