Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/entity.cc7
-rw-r--r--src/core/gameserver.cc41
-rw-r--r--src/model/asefile.cc5
-rw-r--r--src/model/fragment.cc2
-rw-r--r--src/model/fragment.h29
-rw-r--r--src/model/mapfile.cc2
-rw-r--r--src/model/vertexarray.cc3
-rw-r--r--src/model/vertexarray.h11
-rw-r--r--src/render/draw.cc318
-rw-r--r--src/render/gl.cc5
-rw-r--r--src/render/gl.h11
-rw-r--r--src/render/render.cc6
-rw-r--r--src/render/render.h2
-rw-r--r--src/render/state.cc51
-rw-r--r--src/render/state.h9
15 files changed, 318 insertions, 184 deletions
diff --git a/src/core/entity.cc b/src/core/entity.cc
index c76b23a..c99c186 100644
--- a/src/core/entity.cc
+++ b/src/core/entity.cc
@@ -14,6 +14,7 @@
#include "core/cvar.h"
#include "core/application.h"
#include "core/gameinterface.h"
+#include "core/gameserver.h"
#include "BulletCollision/CollisionShapes/btBoxShape.h"
@@ -596,6 +597,12 @@ void EntityDynamic::frame(float seconds)
return;
}
+ if (flag_is_set(KeepAlive)) {
+ if ((keepalive_time() > 0.0f) && (keepalive_time() < server()->time())) {
+ die();
+ }
+ }
+
// transfer bullet state to entity state
if (entity_body) {
// this makes sure an update is sent if speed goes to 0 in the next step
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc
index e6c44d0..344c069 100644
--- a/src/core/gameserver.cc
+++ b/src/core/gameserver.cc
@@ -588,38 +588,35 @@ void GameServer::frame(unsigned long timestamp)
// send network updates
server_network->frame(server_timestamp);
}
-
- // mark all entities as updated
+
const float keepalive_distance_squared = range::fxdistance * range::fxdistance;
+
+ // FIXME KeepAlive sweep has to be done in linear order, O(n^2) is extremely slow with a large number of entities
- for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end();) {
+ for (Entity::Registry::const_iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) {
- // perform a keep-alive pass
- if ((*it).second->flag_is_set(Entity::KeepAlive) && ((*it).second->type() == Entity::Dynamic) && (*it).second->zone()) {
+ // set keepalive timeout
+ if ((*it).second->type() == Entity::Controlable) {
+ const EntityControlable *controlable = static_cast<const EntityControlable *>((*it).second);
- bool keepalive = false;
- EntityDynamic *entity = static_cast<EntityDynamic *>((*it).second);
-
- for (Zone::Content::const_iterator zit = entity->zone()->content().begin(); zit != entity->zone()->content().end(); zit++) {
-
- if (( (*zit)->type() == Entity::Controlable) && ( (*zit) != entity)) {
+ if ( (controlable->state() != Entity::Docked) && controlable->owner() && controlable->zone() ) {
+ for (Zone::Content::iterator zit = controlable->zone()->content().begin(); zit != controlable->zone()->content().end(); zit++) {
- const EntityControlable *other = static_cast<const EntityControlable *>(*zit);
- if (other->owner() && (other->state() != Entity::Docked) && (math::distancesquared(entity->location(), other->location()) < keepalive_distance_squared)) {
- keepalive = true;
+ if ( ((*zit)->flag_is_set(Entity::KeepAlive)) && ((*zit)->type() == Entity::Dynamic) && ((*zit) != controlable) ) {
+ EntityDynamic *dynamic = static_cast<EntityDynamic *>(*zit);
+ if (math::distancesquared(controlable->location(), dynamic->location()) < keepalive_distance_squared) {
+ dynamic->set_keepalive_time(time() + dynamic->keepalive_timeout());
+ }
}
}
-
}
- if (keepalive) {
- entity->set_keepalive_time(time() + entity->keepalive_timeout());
- } else if ((entity->keepalive_time() > 0.0f) && (entity->keepalive_time() < time())) {
- entity->die();
- }
}
-
- // delete the entity if necessary
+ }
+
+ // remove deleted entities and mark remaining entities as updated
+ for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end();) {
+ // remove deleted entities
if ((*it).second->entity_destroyed) {
delete (*it).second;
(*it).second = 0;
diff --git a/src/model/asefile.cc b/src/model/asefile.cc
index f02c450..0275603 100644
--- a/src/model/asefile.cc
+++ b/src/model/asefile.cc
@@ -686,8 +686,9 @@ Model *ASEFile::load(const std::string &name)
model->model_maxbbox.assign (asefile.ase_maxbbox * SCALE);
model->set_radius(math::max(model->model_minbbox.length(), model->model_maxbbox.length()));
- for (FragmentGroup::iterator fit = asefile.fragmentgroup()->begin(); fit != asefile.fragmentgroup()->end(); fit++) {
- Fragment *fragment = (*fit);
+ for (FragmentGroup::Fragments::const_iterator fit = asefile.fragmentgroup()->fragments().begin(); fit != asefile.fragmentgroup()->fragments().end(); fit++) {
+
+ const Fragment *fragment = (*fit);
model->model_tris_count += fragment->structural_size() + fragment->detail_size();
}
model->add_group(asefile.fragmentgroup());
diff --git a/src/model/fragment.cc b/src/model/fragment.cc
index 9071b00..30e89e0 100644
--- a/src/model/fragment.cc
+++ b/src/model/fragment.cc
@@ -74,7 +74,7 @@ FragmentGroup::~FragmentGroup()
void FragmentGroup::clear()
{
- for (iterator it = group_fragments.begin(); it != group_fragments.end(); it++) {
+ for (Fragments::iterator it = group_fragments.begin(); it != group_fragments.end(); it++) {
delete(*it);
}
group_fragments.clear();
diff --git a/src/model/fragment.h b/src/model/fragment.h
index 6d65f7a..9da30b0 100644
--- a/src/model/fragment.h
+++ b/src/model/fragment.h
@@ -81,11 +81,14 @@ class FragmentGroup
public:
enum Type {None = 0, Rotate = 1, Door = 2 };
- typedef std::list<Fragment *>::iterator iterator;
+ /// type definition for a list of model fragments
+ typedef std::list<Fragment *> Fragments;
FragmentGroup();
~FragmentGroup();
+
+ /* ---- inspectors ----------------------------------------- */
inline const Type type() const {
return group_type;
@@ -111,7 +114,16 @@ public:
return group_transform;
}
+ inline const size_t size() const {
+ return group_fragments.size();
+ }
+ inline const Fragments & fragments() const {
+ return group_fragments;
+ }
+
+ /* ---- mutators ------------------------------------------- */
+
inline void set_type(const Type type) {
group_type = type;
}
@@ -136,18 +148,6 @@ public:
group_transform = transform;
}
- inline iterator begin() {
- return group_fragments.begin();
- }
-
- inline iterator end() {
- return group_fragments.end();
- }
-
- inline const size_t size() const {
- return group_fragments.size();
- }
-
inline void add_fragment(Fragment *fragment) {
group_fragments.push_back(fragment);
}
@@ -155,9 +155,6 @@ public:
void clear();
private:
- /// type definition for a list of model fragments
- typedef std::list<Fragment *> Fragments;
-
Fragments group_fragments;
math::Vector3f group_location;
math::Axis group_axis;
diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc
index 6bac44e..e3fda6c 100644
--- a/src/model/mapfile.cc
+++ b/src/model/mapfile.cc
@@ -1451,7 +1451,7 @@ Model * MapFile::load(std::string const &name)
groupdst->set_axis(groupsrc->axis() * tag_submodel->axis());
// copy fragments, this only copies the original fragment's pointer into the vertex array
- for (FragmentGroup::iterator fit = groupsrc->begin(); fit != groupsrc->end(); fit++) {
+ for (FragmentGroup::Fragments::const_iterator fit = groupsrc->fragments().begin(); fit != groupsrc->fragments().end(); fit++) {
Fragment *fragmentdst = new Fragment(*(*fit));
groupdst->add_fragment(fragmentdst);
}
diff --git a/src/model/vertexarray.cc b/src/model/vertexarray.cc
index a559892..d06b976 100644
--- a/src/model/vertexarray.cc
+++ b/src/model/vertexarray.cc
@@ -40,6 +40,7 @@ VertexArray::~VertexArray()
void VertexArray::clear()
{
+ vertex_dirty = true;
vertex_index = 0;
vertex_overflow = false;
@@ -127,6 +128,8 @@ size_t VertexArray::add_vertex(math::Vector3f const &v, math::Vector3f const &n,
}
vertex_index += 8;
+
+ vertex_dirty = true;
return 1;
}
diff --git a/src/model/vertexarray.h b/src/model/vertexarray.h
index 2e43f2a..9a71811 100644
--- a/src/model/vertexarray.h
+++ b/src/model/vertexarray.h
@@ -38,6 +38,11 @@ public:
return vertex_overflow;
}
+ /// return true if the vertex data has changed and needs to uploaded to video memory
+ inline bool dirty() const {
+ return vertex_dirty;
+ }
+
/// pointer to model vertices, sequential in GL_T2F_N3F_V3F format
inline const float *ptr() const {
return vertex_data;
@@ -52,6 +57,10 @@ public:
inline size_t index() const {
return vertex_index;
}
+
+ inline void set_dirty(const bool dirty = true) {
+ vertex_dirty = dirty;
+ }
static inline VertexArray *instance() {
return vertex_instance;
@@ -69,6 +78,8 @@ private:
static VertexArray *vertex_instance;
bool vertex_overflow;
+
+ bool vertex_dirty;
};
}
diff --git a/src/render/draw.cc b/src/render/draw.cc
index 4fc0b60..ed2c8f7 100644
--- a/src/render/draw.cc
+++ b/src/render/draw.cc
@@ -51,6 +51,9 @@ float zone_light[4]; // locaton of the zone light
math::Color zone_color; // color of the zone light
bool has_zone_light = false;
+bool draw_particles = true;
+bool draw_lights = true;
+
typedef std::map<float, core::EntityGlobe *> Globes;
Globes globes_list;
@@ -59,7 +62,18 @@ Globes globes_list;
void pass_prepare(float seconds)
{
using namespace model;
-
+
+ // render settings for this pass_prepare
+ draw_lights = true;
+ if (r_lights && (r_lights->value() <= 0.0f)) {
+ draw_lights = false;
+ }
+
+ draw_particles = true;
+ if (r_particles && (r_particles->value() <= 0.0f)) {
+ draw_particles = false;
+ }
+
// lighting settings for the default light GL_LIGHT0
GLfloat light_position[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat ambient_light[] = { r_ambient->value(), r_ambient->value(), r_ambient->value(), 1.0f };
@@ -506,7 +520,7 @@ void draw_pass_default()
/* ---- Model Fragments -------------------------------------------- */
-void draw_fragment(model::Fragment *fragment, bool draw_details)
+void draw_fragment(const model::Fragment *fragment, bool draw_details)
{
size_t index = fragment->index();
@@ -564,9 +578,9 @@ void draw_model_fragments(model::Model *model,
gl::texgeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
gl::texgeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- for (model::Model::Groups::iterator git = model->groups().begin(); git != model->groups().end(); git++) {
+ for (model::Model::Groups::const_iterator git = model->groups().begin(); git != model->groups().end(); git++) {
- model::FragmentGroup *group = (*git);
+ const model::FragmentGroup *group = (*git);
if (group->transform()) {
gl::push();
@@ -585,9 +599,9 @@ void draw_model_fragments(model::Model *model,
gl::scale(s, s, s);
}
- for (model::FragmentGroup::iterator fit = group->begin(); fit != group->end(); fit++) {
+ for (model::FragmentGroup::Fragments::const_iterator fit = group->fragments().begin(); fit != group->fragments().end(); fit++) {
- model::Fragment *fragment = (*fit);
+ const model::Fragment *fragment = (*fit);
if (fragment->material() != material) {
material = fragment->material();
@@ -930,175 +944,178 @@ void draw_pass_model_fx(float elapsed)
// default light texture
size_t current_texture = Textures::bind("textures/fx/flare00");
gl::enable(GL_TEXTURE_2D);
+
+ if (draw_lights) {
- gl::begin(gl::Quads);
+ gl::begin(gl::Quads);
- // draw model lights
- for (model::Model::Lights::iterator lit = entity->model()->lights().begin(); lit != entity->model()->lights().end(); lit++) {
- model::Light *light = (*lit);
+ // draw model lights
+ for (model::Model::Lights::iterator lit = entity->model()->lights().begin(); lit != entity->model()->lights().end(); lit++) {
+ model::Light *light = (*lit);
- // engine activated lights
- if (light->engine()) {
- if (entity->type() == core::Entity::Controlable) {
- core::EntityControlable *ec = static_cast<core::EntityControlable *>(entity);
- if ((ec->state() == core::Entity::ImpulseInitiate) || (ec->state() == core::Entity::Impulse)) {
- thrust = 1.0f;
- } else {
- thrust = ec->thrust();
- if (thrust < 0.001f) {
- continue; // next light
+ // engine activated lights
+ if (light->engine()) {
+ if (entity->type() == core::Entity::Controlable) {
+ core::EntityControlable *ec = static_cast<core::EntityControlable *>(entity);
+ if ((ec->state() == core::Entity::ImpulseInitiate) || (ec->state() == core::Entity::Impulse)) {
+ thrust = 1.0f;
+ } else {
+ thrust = ec->thrust();
+ if (thrust < 0.001f) {
+ continue; // next light
+ }
}
+ } else {
+ continue; // next light
}
- } else {
- continue; // next light
}
- }
- // strobe frequency
- if (light->strobe()) {
- t = (core::application()->time() + ext_render(entity)->fuzz() - light->offset()) * light->frequency();
- if ((t - floorf(t)) > light->time()) {
- continue; // next light
+ // strobe frequency
+ if (light->strobe()) {
+ t = (core::application()->time() + ext_render(entity)->fuzz() - light->offset()) * light->frequency();
+ if ((t - floorf(t)) > light->time()) {
+ continue; // next light
+ }
}
- }
- // default alpha is 0.8
- a = 0.8f;
- if (light->entity()) {
- color.assign(entity->color());
- } else if (light->engine()) {
- color.assign(entity->model()->enginecolor());
- a *= thrust;
- } else {
- color.assign(light->color());
- }
- color.a = a;
+ // default alpha is 0.8
+ a = 0.8f;
+ if (light->entity()) {
+ color.assign(entity->color());
+ } else if (light->engine()) {
+ color.assign(entity->model()->enginecolor());
+ a *= thrust;
+ } else {
+ color.assign(light->color());
+ }
+ color.a = a;
- location.assign(entity->location() + (entity->axis() * light->location()));
- light_size = 0.0625f * light->radius();
+ location.assign(entity->location() + (entity->axis() * light->location()));
+ light_size = 0.0625f * light->radius();
- // track OpenGL state changes
- if (current_texture != light->texture()) {
- gl::end();
- current_texture = Textures::bind(light->texture());
- gl::begin(gl::Quads);
- }
+ // track OpenGL state changes
+ if (current_texture != light->texture()) {
+ gl::end();
+ current_texture = Textures::bind(light->texture());
+ gl::begin(gl::Quads);
+ }
- // draw the quad
- gl::color(color);
+ // draw the quad
+ gl::color(color);
- glTexCoord2f(0, 1);
- gl::vertex(location + (Camera::axis().up() - Camera::axis().left()) * light_size);
- glTexCoord2f(0, 0);
- gl::vertex(location + (Camera::axis().up() + Camera::axis().left()) * light_size);
- glTexCoord2f(1, 0);
- gl::vertex(location + (Camera::axis().up() * -1 + Camera::axis().left()) * light_size);
- glTexCoord2f(1, 1);
- gl::vertex(location + (Camera::axis().up() * -1 - Camera::axis().left()) * light_size);
- Stats::quads++;
+ glTexCoord2f(0, 1);
+ gl::vertex(location + (Camera::axis().up() - Camera::axis().left()) * light_size);
+ glTexCoord2f(0, 0);
+ gl::vertex(location + (Camera::axis().up() + Camera::axis().left()) * light_size);
+ glTexCoord2f(1, 0);
+ gl::vertex(location + (Camera::axis().up() * -1 + Camera::axis().left()) * light_size);
+ glTexCoord2f(1, 1);
+ gl::vertex(location + (Camera::axis().up() * -1 - Camera::axis().left()) * light_size);
+ Stats::quads++;
- }
+ }
- // draw flares
- for (model::Model::Flares::iterator flit = entity->model()->flares().begin(); flit != entity->model()->flares().end(); flit++) {
- model::Flare *flare = (*flit);
+ // draw flares
+ for (model::Model::Flares::iterator flit = entity->model()->flares().begin(); flit != entity->model()->flares().end(); flit++) {
+ model::Flare *flare = (*flit);
- // engine activated flares
- if (flare->engine()) {
- if (entity->type() == core::Entity::Controlable) {
- core::EntityControlable *ec = static_cast<core::EntityControlable *>(entity);
- if ((ec->state() == core::Entity::ImpulseInitiate) || (ec->state() == core::Entity::Impulse)) {
- thrust = 1.0f;
- } else {
- thrust = ec->thrust();
- if (thrust < 0.001f) {
- continue; // next flare
+ // engine activated flares
+ if (flare->engine()) {
+ if (entity->type() == core::Entity::Controlable) {
+ core::EntityControlable *ec = static_cast<core::EntityControlable *>(entity);
+ if ((ec->state() == core::Entity::ImpulseInitiate) || (ec->state() == core::Entity::Impulse)) {
+ thrust = 1.0f;
+ } else {
+ thrust = ec->thrust();
+ if (thrust < 0.001f) {
+ continue; // next flare
+ }
}
+ } else {
+ continue; // next flare
}
- } else {
- continue; // next flare
}
- }
- // strobe frequency
- if (flare->strobe()) {
- t = (core::application()->time() + ext_render(entity)->fuzz() - flare->offset()) * flare->frequency();
- if ((t - floorf(t)) > flare->time()) {
- continue; // next flare
+ // strobe frequency
+ if (flare->strobe()) {
+ t = (core::application()->time() + ext_render(entity)->fuzz() - flare->offset()) * flare->frequency();
+ if ((t - floorf(t)) > flare->time()) {
+ continue; // next flare
+ }
}
- }
-
- // calulcate viewing angle factor
- flare_axis.assign(entity->axis() * flare->axis());
- a = math::absf(dotproduct(flare_axis.forward(), Camera::axis().forward()));
- if (a < 0.01f) {
- continue; // next flare
- }
- // alpha decreases with viewing angle
- a *= 0.8f;
- if (flare->entity()) {
- color.assign(entity->color());
- } else if (flare->engine()) {
- color.assign(entity->model()->enginecolor());
- a *= thrust;
- } else {
- color.assign(flare->color());
- }
- color.a = a;
+ // calulcate viewing angle factor
+ flare_axis.assign(entity->axis() * flare->axis());
+ a = math::absf(dotproduct(flare_axis.forward(), Camera::axis().forward()));
+ if (a < 0.01f) {
+ continue; // next flare
+ }
- location.assign(entity->location() + (entity->axis() * flare->location()));
- light_size = 0.0625f * flare->radius();
+ // alpha decreases with viewing angle
+ a *= 0.8f;
+ if (flare->entity()) {
+ color.assign(entity->color());
+ } else if (flare->engine()) {
+ color.assign(entity->model()->enginecolor());
+ a *= thrust;
+ } else {
+ color.assign(flare->color());
+ }
+ color.a = a;
- // track OpenGL state changes
- if ((current_cull != flare->cull()) || (current_texture != flare->texture())) {
- gl::end();
+ location.assign(entity->location() + (entity->axis() * flare->location()));
+ light_size = 0.0625f * flare->radius();
- if (current_texture != flare->texture()) {
- current_texture = Textures::bind(flare->texture());
- }
+ // track OpenGL state changes
+ if ((current_cull != flare->cull()) || (current_texture != flare->texture())) {
+ gl::end();
- if (current_cull != flare->cull()) {
- if (flare->cull() == model::CullNone) {
- gl::disable(GL_CULL_FACE);
- current_cull = model::CullNone;
- } else {
- if (current_cull == model::CullNone) {
- gl::enable(GL_CULL_FACE);
- }
+ if (current_texture != flare->texture()) {
+ current_texture = Textures::bind(flare->texture());
+ }
- if (flare->cull() == model::CullBack) {
- gl::cullface(GL_BACK);
- current_cull = model::CullBack;
+ if (current_cull != flare->cull()) {
+ if (flare->cull() == model::CullNone) {
+ gl::disable(GL_CULL_FACE);
+ current_cull = model::CullNone;
} else {
- gl::cullface(GL_FRONT);
- current_cull = model::CullFront;
+ if (current_cull == model::CullNone) {
+ gl::enable(GL_CULL_FACE);
+ }
+
+ if (flare->cull() == model::CullBack) {
+ gl::cullface(GL_BACK);
+ current_cull = model::CullBack;
+ } else {
+ gl::cullface(GL_FRONT);
+ current_cull = model::CullFront;
+ }
}
}
+
+ gl::begin(gl::Quads);
}
- gl::begin(gl::Quads);
- }
+ // draw the quad
+ gl::color(color);
- // draw the quad
- gl::color(color);
+ glTexCoord2f(0, 1);
+ gl::vertex(location + (flare_axis.up() + flare_axis.left()) * light_size);
+ glTexCoord2f(0, 0);
+ gl::vertex(location + (flare_axis.up() - flare_axis.left()) * light_size);
+ glTexCoord2f(1, 0);
+ gl::vertex(location + (flare_axis.up() * -1 - flare_axis.left()) * light_size);
+ glTexCoord2f(1, 1);
+ gl::vertex(location + (flare_axis.up() * -1 + flare_axis.left()) * light_size);
- glTexCoord2f(0, 1);
- gl::vertex(location + (flare_axis.up() + flare_axis.left()) * light_size);
- glTexCoord2f(0, 0);
- gl::vertex(location + (flare_axis.up() - flare_axis.left()) * light_size);
- glTexCoord2f(1, 0);
- gl::vertex(location + (flare_axis.up() * -1 - flare_axis.left()) * light_size);
- glTexCoord2f(1, 1);
- gl::vertex(location + (flare_axis.up() * -1 + flare_axis.left()) * light_size);
+ Stats::quads++;
+ }
- Stats::quads++;
+ gl::end();
}
- gl::end();
-
// draw particle systems
- if (r_particles->value() && ext_render(entity)->particles().size()) {
+ if (draw_particles && ext_render(entity)->particles().size()) {
for (RenderExt::ParticleSystems::iterator it = ext_render(entity)->particles().begin(); it != ext_render(entity)->particles().end(); it++) {
ParticleSystem *particlesystem = (*it);
@@ -1216,9 +1233,29 @@ void draw(float seconds)
if (r_wireframe && r_wireframe->value()) {
glPolygonMode(GL_FRONT, GL_LINE);
}
-
+
+ // check if the vertexarray needs re-uploading
// set vertex array pointers
- glInterleavedArrays(GL_T2F_N3F_V3F, 0, core::game()->vertexarray()->ptr());
+ if (State::has_vbo()) {
+ gl::bindbuffer(GL_ARRAY_BUFFER, State::vbo());
+
+ if (core::game()->vertexarray()->dirty()) {
+ gl::bufferdata(GL_ARRAY_BUFFER, sizeof(float) * core::game()->vertexarray()->index(), core::game()->vertexarray()->ptr(), GL_STATIC_DRAW);
+ core::game()->vertexarray()->set_dirty(false);
+
+ }
+ // Interleaved format is GL_T2F_N3F_V3F
+
+ // void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr )
+ glTexCoordPointer(2, GL_FLOAT, 8 * sizeof(GLfloat), 0);
+ // void glNormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
+ glNormalPointer(GL_FLOAT, 8 * sizeof(GLfloat), (void*) (2 * sizeof(GLfloat)));
+ // void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
+ glVertexPointer(3, GL_FLOAT, 8 * sizeof(GLfloat), (void*) (5 * sizeof(GLfloat)));
+
+ } else {
+ glInterleavedArrays(GL_T2F_N3F_V3F, 0, core::game()->vertexarray()->ptr());
+ }
// enable vertex arrays
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -1261,7 +1298,8 @@ void draw(float seconds)
}
// draw entity lights, flares and particles
- draw_pass_model_fx(seconds);
+ if (draw_lights || draw_particles)
+ draw_pass_model_fx(seconds);
// draw entity radius globe
if (r_radius && r_radius->value()) {
diff --git a/src/render/gl.cc b/src/render/gl.cc
index f97468f..801c320 100644
--- a/src/render/gl.cc
+++ b/src/render/gl.cc
@@ -14,6 +14,11 @@ using math::Vector2f;
using math::Vector3f;
using math::Color;
+genbuffers_func genbuffers = 0;
+deletebuffers_func deletebuffers = 0;
+bindbuffer_func bindbuffer = 0;
+bufferdata_func bufferdata = 0;
+
std::string renderer()
{
return std::string((char *)glGetString(GL_RENDERER));
diff --git a/src/render/gl.h b/src/render/gl.h
index dcac869..222ee0e 100644
--- a/src/render/gl.h
+++ b/src/render/gl.h
@@ -218,6 +218,17 @@ void frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdou
void texgeni(GLenum coord, GLenum param, GLenum value);
void texgenfv(GLenum coord, GLenum param, const GLfloat* value);
+
+typedef void (* genbuffers_func)(GLuint count, GLuint *id);
+typedef void (* deletebuffers_func)(GLuint count, GLuint *id);
+typedef void (* bindbuffer_func)(GLenum target, GLuint id);
+typedef void (* bufferdata_func)(GLenum target, GLsizei size, const GLvoid *data, GLenum usage);
+
+extern genbuffers_func genbuffers;
+extern deletebuffers_func deletebuffers;
+extern bindbuffer_func bindbuffer;
+extern bufferdata_func bufferdata;
+
}
#endif // __INCLUDED_RENDER_GL_H__
diff --git a/src/render/render.cc b/src/render/render.cc
index 398cb6b..baf9465 100644
--- a/src/render/render.cc
+++ b/src/render/render.cc
@@ -31,6 +31,7 @@ namespace render
core::Cvar *r_axis = 0;
core::Cvar *r_bbox = 0;
core::Cvar *r_grid = 0;
+core::Cvar *r_lights = 0;
core::Cvar *r_particles = 0;
core::Cvar *r_radius = 0;
core::Cvar *r_sky = 0;
@@ -66,7 +67,7 @@ void init(int width, int height)
con_print << " renderer ^B" << gl::renderer() << std::endl;
con_print << " vendor ^B" << gl::vendor() << std::endl;
con_print << " version ^B" << gl::version() << std::endl;
-
+
// initialize render state
State::init(width, height);
@@ -97,6 +98,9 @@ void init(int width, int height)
r_particles = core::Cvar::get("r_particles", "1", core::Cvar::Archive);
r_particles->set_info("[bool] render particles");
+
+ r_lights = core::Cvar::get("r_lights", "1", core::Cvar::Archive);
+ r_lights->set_info("[bool] render lights");
r_ambient = core::Cvar::get("r_ambient", "0.1", core::Cvar::Archive);
r_ambient->set_info("[float] ambient light intensity");
diff --git a/src/render/render.h b/src/render/render.h
index 5e5f3d1..97880cc 100644
--- a/src/render/render.h
+++ b/src/render/render.h
@@ -46,6 +46,8 @@ extern core::Cvar *r_axis;
extern core::Cvar *r_bbox;
/// render the spacegrid
extern core::Cvar *r_grid;
+/// render lights and flares
+extern core::Cvar *r_lights;
/// render particle systems
extern core::Cvar *r_particles;
/// render entity radius
diff --git a/src/render/state.cc b/src/render/state.cc
index 1a345c7..df2af75 100644
--- a/src/render/state.cc
+++ b/src/render/state.cc
@@ -7,6 +7,8 @@
#include <string>
#include <sstream>
+#include "SDL/SDL.h"
+
#include "render/state.h"
#include "render/gl.h"
#include "render/render.h"
@@ -17,7 +19,9 @@ namespace render
int State::render_width = 0;
int State::render_height = 0;
float State::render_aspect = 0;
-bool State::render_has_generate_mipmaps = 0;
+bool State::render_has_generate_mipmaps = false;
+bool State::render_has_vbo = false;
+GLuint State::render_vbo = 0;
void State::init(int width, int height)
{
@@ -45,10 +49,55 @@ void State::init(int width, int height)
} else {
con_warn << "Could not determine OpenGL version!" << std::endl;
}
+
+ con_print << " Hardware generate mipmaps ";
+ if (render_has_generate_mipmaps)
+ con_print << "enabled" << std::endl;
+ else
+ con_print << "disabled" << std::endl;
+
+ // initialize gl functions
+ render_has_vbo = true;
+ gl::genbuffers = (gl::genbuffers_func) SDL_GL_GetProcAddress("glGenBuffers");
+ if (!gl::genbuffers) {
+ con_debug << " glGenBuffers not available" << std::endl;
+ render_has_vbo = false;
+ }
+
+ gl::deletebuffers = (gl::deletebuffers_func) SDL_GL_GetProcAddress("glDeleteBuffers");
+ if (!gl::deletebuffers) {
+ con_debug << " glDeleteBuffers not available" << std::endl;
+ render_has_vbo = false;
+ }
+
+ gl::bindbuffer = (gl::bindbuffer_func) SDL_GL_GetProcAddress("glBindBuffer");
+ if (!gl::bindbuffer) {
+ con_debug << " glBindBuffer not available" << std::endl;
+ render_has_vbo = false;
+ }
+
+ gl::bufferdata = (gl::bufferdata_func) SDL_GL_GetProcAddress("glBufferData");
+ if (!gl::bufferdata) {
+ con_debug << " glBufferData not available" << std::endl;
+ render_has_vbo = false;
+ }
+
+ con_print << " Vertex bufer objects ";
+ if (render_has_vbo)
+ con_print << "enabled" << std::endl;
+ else
+ con_print << "disabled" << std::endl;
+
+ // Generate VBO
+ if (render_has_vbo)
+ gl::genbuffers(1, &render_vbo);
}
void State::shutdown()
{
+ // Delete VBO
+ if (render_has_vbo)
+ gl::deletebuffers(1, &render_vbo);
}
void State::resize(int width, int height)
diff --git a/src/render/state.h b/src/render/state.h
index 9a5a67c..3fa3b80 100644
--- a/src/render/state.h
+++ b/src/render/state.h
@@ -7,6 +7,7 @@
#ifndef __INCLUDED_RENDER_STATE_H__
#define __INCLUDED_RENDER_STATE_H__
+#include "render/gl.h"
namespace render
{
@@ -32,6 +33,12 @@ public:
inline static bool has_generate_mipmaps() {
return render_has_generate_mipmaps;
}
+ inline static bool has_vbo() {
+ return render_has_vbo;
+ }
+ inline static GLuint vbo() {
+ return render_vbo;
+ }
private:
static int render_width;
@@ -39,6 +46,8 @@ private:
static float render_aspect;
static bool render_has_generate_mipmaps;
+ static bool render_has_vbo;
+ static GLuint render_vbo;
};
} // namespace render