Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-03-22 22:36:39 +0000
committerStijn Buys <ingar@osirion.org>2008-03-22 22:36:39 +0000
commit7fef8856b21215b0dd28dcc57f04c8a98ab5226f (patch)
tree76288a11fc8138466ee8f76dbf644f29fb0dfbdd
parent8d5cd141d63d9628dbdfebdde462657d5c05f0cf (diff)
Implemented vertex arrays
-rw-r--r--INSTALL10
-rw-r--r--README45
-rw-r--r--osirion.kdevelop.pcsbin526697 -> 518254 bytes
-rw-r--r--osirion.kdevses8
-rw-r--r--src/client/view.cc17
-rw-r--r--src/core/model.cc180
-rw-r--r--src/core/model.h57
-rw-r--r--src/core/netserver.cc2
-rw-r--r--src/render/draw.cc441
-rw-r--r--src/render/draw.h8
-rw-r--r--src/render/render.cc4
-rw-r--r--src/render/render.h2
-rw-r--r--src/render/sphere.cc9
13 files changed, 522 insertions, 261 deletions
diff --git a/INSTALL b/INSTALL
index 3296e35..285747f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -105,7 +105,17 @@ Installing gtkradiant 1.5.0 support files (optional)
Save the changes.
+Source data (optional)
+ The .xcf and .svg source files used to create the game data
+ can also be downloaded. Note that you do not need these files
+ to play the game or to create .map models. You only have to
+ download them them if you want to create new game graphics.
+
+ To download the source data:
+
+ svn checkout svn://intranifty.no-ip.org/osirion-data-src data-src
+
Executing
To run the client program, execute:
diff --git a/README b/README
index 570daa5..6610a90 100644
--- a/README
+++ b/README
@@ -2,15 +2,15 @@
The Osirion Project - README
This is the Osirion project. I wrote it to get a better grasp on
- game design with opengl and to get some C++ practice.
+ game design with OpenGL and to get some C++ practice.
Maybe someday, it will be a real game.
Read INSTALL for instructions on building, installing and udpating.
Dedicated server
- The dedicated server will accept incoming connections on port 8042.
- There is no server console.
+ By default, the dedicated server will accept incoming connections
+ on UDP port 8042. There is no server console.
Client
@@ -79,7 +79,12 @@ Console functions
cl_color 1.0 1.0 0.0
connect
- Settings are saved when you quit the application.
+Configuration
+
+ Variables marked with the 'A' flag will be archived, their value
+ will be written to the configuration file on exit. The dedicated
+ server reads its configuration from server.ini, the client
+ will use client.ini.
Organization of the distribution
@@ -103,6 +108,7 @@ Organization of the distribution
/bitmaps essential bitmaps
/ini ini files
/maps .map models
+ /satellites sattelites
/ships spaceships
/stations space stations
/textures textures
@@ -111,24 +117,24 @@ Organization of the distribution
The game data can be obtained as a seperate distribution.
Refer to the file INSTALLATION for more information.
-Editing game parameters
+Editing game data
One of the goals of the Osirion Project, is to create an engine
- that makes it very easy to extend the game. At this moment, the
- game reads the world description from ini/world.ini and a list of
- buyable ships from ini/ships.ini.
+ that makes it very easy to adapt and extend the game world.
+ At the moment, the game reads the world description from
+ ini/world.ini and a list of buyable ships from ini/ships.ini.
- I recommend not to edit the original game data, but to make a copy
- in your personal osirion folder '~/.osirion'. This directory mimics
- the directory structure of the 'data' directory but any file found
- in the personal diretory will get precedence over the corresponding
- file in the game data directory.
+ I recommend you do not edit the original game data, but to make a copy
+ into your personal osirion folder '~/.osirion'. This directory mimics
+ the directory structure of the 'data' directory and any file found
+ there will get precedence over the corresponding file in
+ the game data directory.
Adding models
The models are basic Quake2 style .map files with custom entities
and can be created with a program like gtkradiant. No map compiler is
- necessary, the engine reads the files directly. Refer to the file
+ necessary, the engine reads the .map files directly. Refer to the file
INSTALL on how to install the support files for gtkradiant 1.5.0.
The textures in the textures/colors/ directory are mapped to RGB colors
@@ -141,7 +147,7 @@ Adding models
texture will get the current game entity color. This makes it possible
to use the current player color on ship models.
- Add an info_engine entity to add an engine exhaust to the ship model.
+ Add an info_engine entity to add an engine exhaust to a ship model.
Notes
@@ -153,12 +159,19 @@ Notes
Project contributors
- Thorn[mDc] - Ship models
+ Thorn[mDc] - Canasta and Sharkan ship models
+ Alpha testing
+ Josky=KCT= - Shuttle ship model
IRC
The official Osirion IRC channel is #osirion on irc.soliter.org
+Web
+
+ Screenshots can be found at
+ http://ingar.soliter.org/screenshots/osirion
+
Acknowledgements
This project could not have been possible without the work of others:
diff --git a/osirion.kdevelop.pcs b/osirion.kdevelop.pcs
index e58b241..b0fd24b 100644
--- a/osirion.kdevelop.pcs
+++ b/osirion.kdevelop.pcs
Binary files differ
diff --git a/osirion.kdevses b/osirion.kdevses
index c865c2a..5dd7e63 100644
--- a/osirion.kdevses
+++ b/osirion.kdevses
@@ -2,11 +2,11 @@
<!DOCTYPE KDevPrjSession>
<KDevPrjSession>
<DocsAndViews NumberOfDocuments="2" >
- <Doc0 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/core/netclient.cc" >
- <View0 Encoding="" line="112" Type="Source" />
+ <Doc0 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/render/draw.cc" >
+ <View0 Encoding="" line="453" Type="Source" />
</Doc0>
- <Doc1 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/core/netserver.cc" >
- <View0 Encoding="" line="78" Type="Source" />
+ <Doc1 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/game/game.h" >
+ <View0 Encoding="" line="32" Type="Source" />
</Doc1>
</DocsAndViews>
<pluginList>
diff --git a/src/client/view.cc b/src/client/view.cc
index 466723f..5d14992 100644
--- a/src/client/view.cc
+++ b/src/client/view.cc
@@ -56,7 +56,7 @@ void reset()
GLfloat ambient_light[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat diffuse_light[] = { 0.4f, 0.4f, 0.4f, 1.0f };
GLfloat specular_light[] = { 0.4f, 0.4f, 0.4f, 1.0f };
- GLfloat specular_reflectance[] = { 0.5f, 0.5f, 0.5f, 1.0f };
+ GLfloat specular_reflectance[] = { 0.2f, 0.2f, 0.2f, 1.0f };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_light);
@@ -85,6 +85,8 @@ void reset()
// alpha-blending
gl::blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl::enable(GL_BLEND);
+
+ // client state
}
void draw_loader()
@@ -130,7 +132,7 @@ void draw_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 " << std::setfill('0') << std::setw(2) << hours << ":"
+ status << "clock " << std::setfill('0') << std::setw(2) << hours << ":"
<< std::setfill('0') << std::setw(2) << minutes << ":"
<< std::setfill('0') << std::setw(2) << seconds;
@@ -138,9 +140,18 @@ void draw_status()
seconds = (int) floorf(core::application()->time() - (float) minutes* 60.0f);
status << " time " << std::setfill('0') << std::setw(2) << minutes << ":" << std::setfill('0') << std::setw(2) << seconds;
- status << " fps " << std::setw(4) << fps;
+
draw_text(CHARWIDTH, 4, status);
+ // print stats if desired
+ if (render::r_drawstats && render::r_drawstats->value()) {
+ std::stringstream stats;
+ stats << "fps " << std::setw(6) << fps << "\n";
+ stats << "tris " << std::setw(6) << render::Stats::tris << "\n";
+ stats << "spheres " << std::setw(4) << render::Stats::spheres << "\n";
+ draw_text(video::width-CHARWIDTH*13, CHARHEIGHT*3, stats);
+ }
+
// print the version number in the upper right corner
gl::color(0.0f, 1.0f, 0.0f, 1.0f);
std::string version("ver. ");
diff --git a/src/core/model.cc b/src/core/model.cc
index 88a1040..df6e563 100644
--- a/src/core/model.cc
+++ b/src/core/model.cc
@@ -12,6 +12,7 @@
#include <vector>
#include <list>
+#include "core/cvar.h"
#include "core/model.h"
#include "filesystem/filesystem.h"
@@ -21,6 +22,64 @@ namespace core
const float MAX_BOUNDS = 8192;
const float delta = 10e-10;
+const size_t VERTEXARRAYVERTEXARRAYSIZE=65536*3;
+
+/* ---------- core::VertexArray ------------------------------------ */
+float VertexArray::vertex[VERTEXARRAYSIZE];
+float VertexArray::vertex_color[VERTEXARRAYSIZE];
+float VertexArray::vertex_normal[VERTEXARRAYSIZE];
+
+float VertexArray::evertex[VERTEXARRAYSIZE];
+float VertexArray::evertex_normal[VERTEXARRAYSIZE];
+
+size_t VertexArray::vertex_index;
+size_t VertexArray::evertex_index;
+
+void VertexArray::clear()
+{
+ memset(vertex, 0, sizeof(vertex));
+ memset(vertex_color, 0, sizeof(vertex_color));
+ memset(vertex_normal, 0, sizeof(vertex_normal));
+
+ memset(evertex, 0, sizeof(evertex));
+ memset(evertex_normal, 0, sizeof(evertex_normal));
+
+ vertex_index = 0;
+ evertex_index = 0;
+}
+
+void VertexArray::add_vertex(math::Vector3f const &v, math::Vector3f const &n, math::Color const &color) {
+ if (vertex_index + 3 >= VERTEXARRAYSIZE) {
+ con_warn << "VertexArray overflow!" << std::endl;
+ return;
+ }
+
+ for (int i = 0; i < 3; i ++) {
+ vertex[vertex_index+i] = v[i];
+ vertex_normal[vertex_index+i] = n[i];
+ }
+
+ vertex_color[vertex_index] = color.r;
+ vertex_color[vertex_index+1] = color.g;
+ vertex_color[vertex_index+2] = color.b;
+
+ vertex_index += 3;
+}
+
+void VertexArray::add_evertex(math::Vector3f const &v, math::Vector3f const &n) {
+ if (evertex_index + 3 >= VERTEXARRAYSIZE) {
+ con_warn << "EVertexArray overflow!" << std::endl;
+ return;
+ }
+
+ for (int i = 0; i < 3; i ++) {
+ evertex[evertex_index+i] = v[i];
+ evertex_normal[evertex_index+i] = n[i];
+ }
+
+ evertex_index += 3;
+}
+
/* ---------- core::Light ------------------------------------------ */
Light::Light(math::Vector3f const & location, math::Color const & color) :
@@ -40,38 +99,6 @@ Engine::Engine(math::Vector3f const & location) :
Engine::~Engine()
{}
-/* ---------- core::Face ------------------------------------------ */
-
-Face::Face(math::Vector3f const & normal, math::Color const *color) :
- face_normal(normal)
-{
- face_normal.normalize();
-
- if (color)
- face_color = new math::Color(*color);
- else
- face_color = 0;
-}
-
-Face::~Face()
-{
- for (std::vector<math::Vector3f *>::iterator it = face_vertex.begin(); it != face_vertex.end(); it++) {
- delete (*it);
- }
-
- face_vertex.clear();
-
- if (face_color)
- delete face_color;
-}
-
-void Face::add_vertex(math::Vector3f const & vertex)
-{
- math::Vector3f *v = new math::Vector3f(vertex);
-
- face_vertex.push_back(v);
-}
-
/* ---------- core::Model ------------------------------------------ */
std::map<std::string, Model*> Model::registry;
@@ -81,6 +108,10 @@ Model::Model(std::string const & name) :
{
model_valid = false;
model_scale = 1.0f / 1024.0f;
+ model_first_vertex = 0;
+ model_first_evertex = 0;
+ model_vertex_count = 0;
+ model_evertex_count = 0;
std::string fn("maps/");
fn.append(name);
@@ -113,6 +144,9 @@ Model::Model(std::string const & name) :
math::Vector3f class_origin;
float class_angle;
math::Color class_color;
+
+ model_first_evertex = VertexArray::evertex_index/3;
+ model_first_vertex = VertexArray::vertex_index/3;
while (ifs) {
ifs.getline(data, 1023);
@@ -135,14 +169,15 @@ Model::Model(std::string const & name) :
} else if (firstword == "}") {
//cout << " LEVEL -" << level << std::endl;
if ((level == 2) && (class_name == "worldspawn")) {
- //cout << "brush with " << planes.size() << " faces" << std::endl;
-
- // for every face
- std::vector<Vector3f *>points;
- for (std::vector<Plane3f *>::iterator face = planes.begin(); face != planes.end(); face++) {
- make_face((*face), planes);
+
+ if (!(Cvar::sv_dedicated && Cvar::sv_dedicated->value())) {
+ // for every face
+ std::vector<Vector3f *>points;
+ for (std::vector<Plane3f *>::iterator face = planes.begin(); face != planes.end(); face++) {
+ make_face((*face), planes);
+ }
}
-
+
// clean planes
for (std::vector<Plane3f *>::iterator it = planes.begin(); it != planes.end(); it++) {
delete(*it);
@@ -246,7 +281,7 @@ Model::Model(std::string const & name) :
ifs.close();
- if (model_face.size()) {
+ if ((model_vertex_count + model_evertex_count) > 0 ) {
if (model_maxbbox.lengthsquared() > model_minbbox.lengthsquared()) {
model_radius = model_maxbbox.length();
} else {
@@ -254,17 +289,12 @@ Model::Model(std::string const & name) :
}
model_valid = true;
}
- con_debug << " maps/" << name << ".map " << model_face.size() << " polygons\n";
+ //con_debug << " maps/" << name << ".map " << model_face.size() << " polygons\n";
+ con_debug << " maps/" << name << ".map " << (model_vertex_count + model_evertex_count)/3 << " triangles" << std::endl;
}
Model::~Model()
{
- // delete all faces
- for (std::list<Face *>::iterator fit = model_face.begin(); fit != model_face.end(); fit++) {
- delete(*fit);
- }
- model_face.clear();
-
// delete all engines
for (std::list<Engine *>::iterator eit = model_engine.begin(); eit != model_engine.end(); eit++) {
delete(*eit);
@@ -291,7 +321,6 @@ void Model::make_face(math::Plane3f *face, std::vector<math::Plane3f *> & planes
// using suggestions from
// http://www.flipcode.com/archives/Level_Editing.shtml
- //cout << "Face with normal " << face->normal() << endl;
std::vector<math::Vector3f *> vl;
// inital vertexes
@@ -496,28 +525,46 @@ void Model::make_face(math::Plane3f *face, std::vector<math::Plane3f *> & planes
} else
color = new math::Color(1.0f, 0.0, 1.0f);
- /*
+ // calculate bounding box
+ for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
+
+ *(*it) *= model_scale;
+
+ for (int i=0; i < 3; i++) {
+ if (model_maxbbox[i] < (*(*it))[i])
+ model_maxbbox[i] = (*(*it))[i];
+
+ if (model_minbbox[i] > (*(*it))[i])
+ model_minbbox[i] = (*(*it))[i];
+ }
+ }
+
// split face into triangles
while (vl.size() >2 ) {
std::vector<Vector3f *>::iterator v0 = vl.begin();
std::vector<Vector3f *>::reverse_iterator vn = vl.rbegin();
std::vector<Vector3f *>::reverse_iterator vn1 = vl.rbegin();
++vn1;
- */
- Face *mf = new Face(face->normal()*-1, color);
- for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) {
- mf->add_vertex(*(*it) * model_scale);
- // bounding box
- for (int i=0; i < 3; i++) {
- if (model_maxbbox[i] < (*(*it))[i] * model_scale)
- model_maxbbox[i] = (*(*it))[i] * model_scale;
-
- if (model_minbbox[i] > (*(*it))[i] * model_scale)
- model_minbbox[i] = (*(*it))[i] * model_scale;
+ Vector3f n(face->normal()*-1);
+ n.normalize();
+
+ if (!color) {
+ VertexArray::add_evertex(*(*vn1), n);
+ VertexArray::add_evertex(*(*vn), n);
+ VertexArray::add_evertex(*(*v0), n);
+ model_evertex_count += 3;
+ } else {
+ VertexArray::add_vertex(*(*vn1), n, *color);
+ VertexArray::add_vertex(*(*vn), n, *color);
+ VertexArray::add_vertex(*(*v0), n, *color);
+ model_vertex_count += 3;
}
+
+ delete (*vn);
+ vl.pop_back();
}
- add_face(mf);
+ //add_face(mf);
if (color) delete color;
} else {
con_debug << "Unresolved face!\n";
@@ -531,11 +578,6 @@ void Model::make_face(math::Plane3f *face, std::vector<math::Plane3f *> & planes
}
-void Model::add_face(Face *face)
-{
- model_face.push_back(face);
-}
-
void Model::add_engine(Engine *engine)
{
model_engine.push_back(engine);
@@ -572,12 +614,16 @@ void Model::clear()
delete(*mit).second;
}
registry.clear();
+
+ // clear the vertex array
+ VertexArray::clear();
}
void Model::list()
{
for (std::map<std::string, Model*>::iterator mit = registry.begin(); mit != registry.end(); mit++) {
- con_print << " " << (*mit).second->model_name << " " << (*mit).second->model_face.size() << " polys "
+ con_print << " " << (*mit).second->name() << " "
+ << ((*mit).second->vertex_count() + (*mit).second->evertex_count())/3 << " triangles "
<< (*mit).second->model_engine.size() << " engines "
<< (*mit).second->model_light.size() << " lights\n";
}
diff --git a/src/core/model.h b/src/core/model.h
index 00c8a48..5deee35 100644
--- a/src/core/model.h
+++ b/src/core/model.h
@@ -18,27 +18,31 @@
namespace core
{
-/// one face (polygon) of a model
-class Face {
+/// Global vertex array
+
+
+const size_t VERTEXARRAYSIZE=65536*512;
+
+class VertexArray
+{
public:
- Face(math::Vector3f const & normal, math::Color const *color=0);
- ~Face();
+ /// model vertices
+ static float vertex[VERTEXARRAYSIZE];
+ static float vertex_color[VERTEXARRAYSIZE];
+ static float vertex_normal[VERTEXARRAYSIZE];
- /// the normal of this face
- inline math::Vector3f const & normal() const { return face_normal; };
+ /// model vertices with entity color
+ static float evertex[VERTEXARRAYSIZE];
+ static float evertex_normal[VERTEXARRAYSIZE];
- /// the color of this face
- inline math::Color const *color() const { return face_color; };
+ static size_t vertex_index;
+ static size_t evertex_index;
- /// add a vertex to the face
- void add_vertex(math::Vector3f const &vertex);
+ static void clear();
- /// face vertexes
- std::vector<math::Vector3f *> face_vertex;
+ static void add_vertex(math::Vector3f const &v, math::Vector3f const &n, math::Color const &color);
+ static void add_evertex(math::Vector3f const &v, math::Vector3f const &n);
-private:
- math::Vector3f face_normal;
- math::Color *face_color;
};
@@ -95,6 +99,18 @@ public:
/// minimum values of the bounding box
inline math::Vector3f const & minbbox() const { return model_minbbox; }
+ /// first vertex in the global VertexArray
+ inline size_t first_vertex() const { return model_first_vertex; }
+
+ /// number of vertexes in this model
+ inline size_t vertex_count() const { return model_vertex_count; }
+
+ /// first vertex in the global VertexArray
+ inline size_t first_evertex() const { return model_first_evertex; }
+
+ /// number of vertexes in this model
+ inline size_t evertex_count() const { return model_evertex_count; }
+
/// radius
inline float radius() const { return model_radius; }
@@ -115,19 +131,17 @@ public:
/// list the content of the model registry
static void list();
- /// list of Faces
- std::list<Face *> model_face;
-
/// list of Engines
std::list<Engine *> model_engine;
/// list of Lights
std::list<Light *> model_light;
+
+
private:
void make_face(math::Plane3f *face, std::vector<math::Plane3f *> & planes);
void add_engine(Engine *engine);
- void add_face(Face *face);
void add_light(Light *light);
std::string model_name;
@@ -138,6 +152,11 @@ private:
math::Vector3f model_maxbbox;
math::Vector3f model_minbbox;
+
+ size_t model_first_vertex;
+ size_t model_vertex_count;
+ size_t model_first_evertex;
+ size_t model_evertex_count;
};
}
diff --git a/src/core/netserver.cc b/src/core/netserver.cc
index c8c0a9d..16beee0 100644
--- a/src/core/netserver.cc
+++ b/src/core/netserver.cc
@@ -284,7 +284,7 @@ void NetServer::broadcast(std::string const & message, Player *ignore_player)
}
}
-// find the client corresponding to a player id
+// find the client corresponding to a player
NetClient *NetServer::find_client(Player const *player)
{
for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
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();