Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2009-08-10 22:32:36 +0000
committerStijn Buys <ingar@osirion.org>2009-08-10 22:32:36 +0000
commitbd142a328328cdf0cbfbb59e4e0aa99dd51184b8 (patch)
treec2ed4e832e60b379723ea3f530c5b192bec0da61 /src
parentbbd04914749b2e3918796fe331daf649b06163ea (diff)
initial texture support for ase models
Diffstat (limited to 'src')
-rw-r--r--src/model/asefile.cc115
-rw-r--r--src/model/asefile.h12
-rw-r--r--src/model/fragment.cc11
-rw-r--r--src/model/fragment.h4
-rw-r--r--src/model/map.cc13
-rw-r--r--src/model/material.cc38
-rw-r--r--src/model/material.h50
-rw-r--r--src/model/triangle.h24
-rw-r--r--src/render/draw.cc56
9 files changed, 272 insertions, 51 deletions
diff --git a/src/model/asefile.cc b/src/model/asefile.cc
index 7b574d7..f4f3342 100644
--- a/src/model/asefile.cc
+++ b/src/model/asefile.cc
@@ -33,6 +33,11 @@ ASEFile::ASEFile(std::string const &name)
ASEFile::~ASEFile()
{
+ for (VertexList::iterator it = ase_tvertexlist.begin(); it != ase_tvertexlist.end(); it++) {
+ delete (*it).second;
+ }
+ ase_tvertexlist.clear();
+
for (VertexList::iterator it = ase_vertexlist.begin(); it != ase_vertexlist.end(); it++) {
delete (*it).second;
}
@@ -126,7 +131,7 @@ bool ASEFile::read_mesh_face_list(std::istream &is)
line >> word;
if (word.compare("}") == 0) {
- con_debug << count << " mesh faces" << std::endl;
+ con_debug << " " << count << " mesh faces" << std::endl;
return true;
} else if ( word.compare("*MESH_FACE") == 0) {
@@ -160,6 +165,8 @@ bool ASEFile::read_mesh_normals(std::istream &is)
char data[1024];
memset(data, 0, sizeof(data));
+ size_t count = 0;
+
size_t index = 0;
size_t vertindex = 0;
float x, y, z;
@@ -172,6 +179,7 @@ bool ASEFile::read_mesh_normals(std::istream &is)
line >> firstword;
if (firstword.compare("}") == 0) {
+ con_debug << " " << count << " face normals" << std::endl;
return true;
} else if ( firstword.compare("*MESH_FACENORMAL") == 0) {
@@ -179,6 +187,7 @@ bool ASEFile::read_mesh_normals(std::istream &is)
it = ase_facelist.find(index);
if (it != ase_facelist.end()) {
(*it).second->normal().assign(x, y, z);
+ count++;
} else {
con_debug << " could not find face " << index << std::endl;
}
@@ -205,6 +214,76 @@ bool ASEFile::read_mesh_normals(std::istream &is)
return false;
}
+bool ASEFile::read_mesh_tvertex_list(std::istream &is)
+{
+ size_t count = 0;
+
+ char data[1024];
+ memset(data, 0, sizeof(data));
+
+ while (is.getline(data, sizeof(data) -1 )) {
+ std::istringstream line(data);
+
+ std::string firstword;
+ line >> firstword;
+
+ if (firstword.compare("}") == 0) {
+ con_debug << " " << count << " texture vertices" << std::endl;
+ return true;
+
+ } else if ( firstword.compare("*MESH_TVERT") == 0) {
+ size_t index;
+ float x, y, z;
+ if (line >> index >> x >> y >> z) {
+ math::Vector3f *v = new math::Vector3f(x, y, z);
+ ase_tvertexlist[index] = v;
+ count++;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool ASEFile::read_mesh_tface_list(std::istream &is)
+{
+size_t count = 0;
+
+ char data[1024];
+ memset(data, 0, sizeof(data));
+
+ while (is.getline(data, sizeof(data) -1 )) {
+ std::istringstream line(data);
+
+ std::string firstword;
+ line >> firstword;
+
+ if (firstword.compare("}") == 0) {
+ con_debug << " " << count << " face texture coordinates" << std::endl;
+ return true;
+
+ } else if ( firstword.compare("*MESH_TFACE") == 0) {
+ size_t index, a, b, c;
+ if (line >> index >> a >> b >> c) {
+ Triangle *triangle = ase_facelist[index];
+ math::Vector3f *t0 = ase_tvertexlist[a];
+ math::Vector3f *t1 = ase_tvertexlist[b];
+ math::Vector3f *t2 = ase_tvertexlist[c];
+ if (triangle) {
+ if (t0)
+ triangle->t0().assign(t0->x, t0->y);
+ if (t1)
+ triangle->t1().assign(t1->x, t1->y);
+ if (t2)
+ triangle->t2().assign(t2->x, t2->y);
+ }
+ count++;
+ }
+ }
+ }
+
+ return false;
+}
bool ASEFile::read_mesh(std::istream &is)
{
@@ -238,6 +317,18 @@ bool ASEFile::read_mesh(std::istream &is)
read_mesh_normals(is);
}
+ } else if ((level == 1 ) && (word.compare("*MESH_TVERTLIST") == 0)) {
+ if ((line >> word) && (word.compare("{") == 0)) {
+ con_debug << " " << name() << " *MESH_TVERTLIST" << std::endl;
+ read_mesh_tvertex_list(is);
+ }
+
+ } else if ((level == 1 ) && (word.compare("*MESH_TFACELIST") == 0)) {
+ if ((line >> word) && (word.compare("{") == 0)) {
+ con_debug << " " << name() << " *MESH_TFACELIST" << std::endl;
+ read_mesh_tface_list(is);
+ }
+
} else {
do {
@@ -337,11 +428,12 @@ Model * ASEFile::load(const std::string &name)
Model *model = new Model(name);
// default material
- Material *material = Material::find("textures/common/entity");
+ Material *material = Material::find("models/" + name);
if (!material) {
- material = new Material("placeholder");
+ material = new Material("models/" + name);
Material::add(material);
- material->set_flags(Material::Primary);
+ material->set_flags(Material::Texture);
+ material->set_texture(material->name());
}
// a single fragment for all the model triangles
@@ -353,18 +445,21 @@ Model * ASEFile::load(const std::string &name)
// calculate model center
math::Vector3f center((asefile.ase_minbbox + asefile.ase_maxbbox) * 0.5f);
- model->model_minbbox = asefile.ase_minbbox - center;
- model->model_maxbbox = asefile.ase_maxbbox - center;
+ //const float scale = SCALE;
+ const float scale = 0.125f;
- model->model_radius = asefile.ase_minbbox.length();
+ // caculate bounding box
+ model->model_minbbox = (asefile.ase_minbbox - center) * scale;
+ model->model_maxbbox = (asefile.ase_maxbbox - center) * scale;
+ model->model_radius = model->model_maxbbox.length();
// load the model faces into the fragment
for (FaceList::iterator it = asefile.ase_facelist.begin(); it != asefile.ase_facelist.end(); it++) {
Triangle *triangle = (*it).second;
- fragment->add_vertex(triangle->v0() - center , triangle->n0(), false);
- fragment->add_vertex(triangle->v1() - center , triangle->n1(), false);
- fragment->add_vertex(triangle->v2() - center , triangle->n2(), false);
+ fragment->add_vertex((triangle->v0() - center) * scale , triangle->n0(), triangle->t0(), false);
+ fragment->add_vertex((triangle->v1() - center) * scale , triangle->n1(), triangle->t1(), false);
+ fragment->add_vertex((triangle->v2() - center) * scale , triangle->n2(), triangle->t2(), false);
model->model_tris_count++;
model->model_tris_detail_count++;
diff --git a/src/model/asefile.h b/src/model/asefile.h
index 7f5ab03..dc1516b 100644
--- a/src/model/asefile.h
+++ b/src/model/asefile.h
@@ -55,6 +55,16 @@ private:
bool read_mesh_vertex_list(std::istream &is);
/**
+ * @brief read *MESH_TVERTLIST
+ */
+ bool read_mesh_tvertex_list(std::istream &is);
+
+ /**
+ * @brief read *MESH_TFACELIST
+ */
+ bool read_mesh_tface_list(std::istream &is);
+
+ /**
* @brief read *MESH
*/
bool read_mesh(std::istream &is);
@@ -84,6 +94,8 @@ private:
VertexList ase_vertexlist;
+ VertexList ase_tvertexlist;
+
FaceList ase_facelist;
math::Vector3f ase_maxbbox;
diff --git a/src/model/fragment.cc b/src/model/fragment.cc
index 7765b7e..72d8e2a 100644
--- a/src/model/fragment.cc
+++ b/src/model/fragment.cc
@@ -37,6 +37,17 @@ size_t Fragment::add_vertex(math::Vector3f const & vertex, math::Vector3f const
return n;
}
+size_t Fragment::add_vertex(math::Vector3f const & vertex, math::Vector3f const &normal, math::Vector2f const &texcoord, bool detail)
+{
+ size_t n = VertexArray::instance()->add_vertex(vertex, normal, texcoord.x, texcoord.y);
+ if (n) {
+ if (detail)
+ fragment_detail_size += n;
+ else
+ fragment_structural_size += n;
+ }
+ return n;
+}
/* ---- class FragmentGroup ---------------------------------------- */
FragmentGroup::FragmentGroup()
diff --git a/src/model/fragment.h b/src/model/fragment.h
index e975734..9d992e1 100644
--- a/src/model/fragment.h
+++ b/src/model/fragment.h
@@ -11,6 +11,7 @@
#include "math/axis.h"
#include "math/vector3f.h"
+#include "math/vector2f.h"
#include "model/material.h"
namespace model
@@ -28,6 +29,9 @@ public:
/// add a vertex to the fragment
size_t add_vertex(math::Vector3f const & vertex, math::Vector3f const &normal, bool detail);
+
+ /// add a vertex to the fragment
+ size_t add_vertex(math::Vector3f const & vertex, math::Vector3f const &normal, math::Vector2f const &texcoord, bool detail);
/// the type of primitives this fragment consists of
inline Type type() const
diff --git a/src/model/map.cc b/src/model/map.cc
index 8165e3a..9cb5295 100644
--- a/src/model/map.cc
+++ b/src/model/map.cc
@@ -434,16 +434,13 @@ void Map::make_brushface(Plane *face)
if (vl.size() > 2) {
- Material *material = Material::find(face->texture());
+ Material *material = Material::find("textures/" + face->texture());
+
if (!material) {
- material = new Material(face->texture());
+ material = new Material("textures/" + face->texture());
Material::add(material);
- material->set_color(math::Color(1.0, 0.0f, 1.0f));
- material->set_flags(Material::Bright);
-
- // don't show material warnings on a dedicated server
- if (VertexArray::instance())
- con_warn << "Unkown material '" << face->texture() << "'" << std::endl;
+ material->set_flags(Material::Texture);
+ material->set_texture(material->name());
}
// find the list if primitives for the current material, allocate a new one if necessary
diff --git a/src/model/material.cc b/src/model/material.cc
index 81adfae..7d278f9 100644
--- a/src/model/material.cc
+++ b/src/model/material.cc
@@ -19,6 +19,7 @@ Material::Material(const std::string &name) : material_name(name), material_colo
{
aux::to_lowercase(material_name);
material_flags = 0;
+ material_texture_id = 0;
}
Material::~Material()
@@ -31,6 +32,16 @@ void Material::set_color(const math::Color &color)
material_color.a = 1.0f;
}
+void Material::set_texture(const std::string &texture)
+{
+ material_texture.assign(texture);
+}
+
+void Material::set_texture_id(const size_t texture_id)
+{
+ material_texture_id = texture_id;
+}
+
Material::Registry Material::material_registry;
void Material::init()
@@ -113,17 +124,14 @@ void Material::load_shader(const std::string &shadername)
} else if ((firstword.size()) && (parselevel == 0) ) {
- if (firstword.compare(0, 9, "textures/") == 0) {
- firstword.erase(0, 9);
- material = find(firstword);
- if (material) {
- con_warn << "Duplicate material '" << firstword << "'" << std::endl;
- } else {
- material = new Material(firstword);
- add(material);
- //con_debug << " " << firstword << std::endl;
- }
+ material = find(firstword);
+ if (material) {
+ con_warn << "Duplicate material '" << firstword << "'" << std::endl;
+ } else {
+ material = new Material(firstword);
+ add(material);
count++;
+ //con_debug << " " << firstword << std::endl;
}
} else if ((parselevel == 1) && (material)) {
@@ -151,6 +159,16 @@ void Material::load_shader(const std::string &shadername)
continue;
} else if (firstword.compare("qer_trans") == 0) {
continue;
+ } else if (firstword.compare("texture") == 0) {
+
+ // texture name should not contain spaces
+ if (linestream >> firstword) {
+ material->set_texture(firstword);
+ material->set_flags(Material::Texture);
+ } else {
+ con_warn << shaderfile.name() << " texture key without filename at line " << linenumber << std::endl;
+ }
+
} else {
con_warn << shaderfile.name() << " unknown key '" << firstword
<< "' at line " << linenumber << std::endl;
diff --git a/src/model/material.h b/src/model/material.h
index a2ba0d6..9072a4d 100644
--- a/src/model/material.h
+++ b/src/model/material.h
@@ -20,20 +20,35 @@ class Material
{
public:
/// surface flags
- enum SurfaceFlags { None=0, Primary=1, Secondary=2, Tertiary=3, Bright=4, Engine=8, Environment=16};
+ enum SurfaceFlags { None=0, Primary=1, Secondary=2, Tertiary=3, Bright=4, Engine=8, Environment=16, Texture=32};
/// type definition for the material registry
typedef std::map<std::string, Material *> Registry;
Material(const std::string &name);
+
~Material();
+ /* ---- inspectors ----------------------------------------- */
+
inline const std::string &name() const { return material_name; }
inline const math::Color &color() const { return material_color; }
inline const unsigned int flags() const { return material_flags; }
+ inline const std::string &texture() const { return material_texture; }
+
+ inline const size_t texture_id() const { return material_texture_id; }
+
+ /* ---- mutators ------------------------------------------- */
+
+ void set_color(const math::Color &color);
+
+ void set_texture(const std::string &texture);
+
+ void set_texture_id(const size_t texture_id);
+
inline void set_flags(SurfaceFlags flags)
{
material_flags |= flags;
@@ -43,31 +58,38 @@ public:
{
material_flags &= ~flags;
}
-
-
- void set_color(const math::Color &color);
-/* ---- static ----------------------------------------------------- */
+ /* ---- static ----------------------------------------------------- */
/**
- * @brief initialize materials
- * reads materials from the shader files
+ * @brief initialize material registry
+ * reads materials from the shader files listed in shaderlist.txt
*/
static void init();
- /// clear all materials
+ /**
+ * @brief shutdown material registry
+ */
static void shutdown();
- /// clear all materials
+ /**
+ * @brief clear material registry
+ */
static void clear();
- /// list registered materials
+ /**
+ * @brief print registered materials to the system console
+ */
static void list();
- /// add a material to the registry
+ /**
+ * @brief add a material to the registry
+ */
static void add(Material *material);
- /// find a material in the registry
+ /**
+ * @brief find a material in the registry
+ */
static Material *find(const std::string &name);
private:
@@ -75,8 +97,10 @@ private:
std::string material_name;
math::Color material_color;
unsigned int material_flags;
+ std::string material_texture;
+ size_t material_texture_id;
- /// the material registry
+ /// the materials registry
static Registry material_registry;
static void load_shader(const std::string &shadername);
diff --git a/src/model/triangle.h b/src/model/triangle.h
index fe1c720..a3fb643 100644
--- a/src/model/triangle.h
+++ b/src/model/triangle.h
@@ -8,6 +8,7 @@
#define __INCLUDED_MODEL_TRIANGLE_H__
#include "math/color.h"
+#include "math/vector2f.h"
#include "math/vector3f.h"
namespace model
@@ -78,6 +79,12 @@ public:
return triangle_n0;
}
+ /// triangle vertex 0 texture coordinates
+ inline math::Vector2f & t0()
+ {
+ return triangle_t0;
+ }
+
/// triangle vertex 1
inline math::Vector3f & v1()
{
@@ -89,6 +96,12 @@ public:
{
return triangle_n1;
}
+
+ /// triangle vertex 1 texture coordinates
+ inline math::Vector2f & t1()
+ {
+ return triangle_t1;
+ }
/// triangle vertex 2
inline math::Vector3f & v2()
@@ -96,22 +109,31 @@ public:
return triangle_v2;
}
- /// triangle vertex 0 normal
+ /// triangle vertex 2 normal
inline math::Vector3f & n2()
{
return triangle_n2;
}
+ /// triangle vertex 2 texture coordinates
+ inline math::Vector2f & t2()
+ {
+ return triangle_t2;
+ }
+
private:
math::Vector3f triangle_v0;
math::Vector3f triangle_n0;
+ math::Vector2f triangle_t0;
math::Vector3f triangle_v1;
math::Vector3f triangle_n1;
+ math::Vector2f triangle_t1;
math::Vector3f triangle_v2;
math::Vector3f triangle_n2;
+ math::Vector2f triangle_t2;
math::Vector3f triangle_normal;
bool triangle_detail;
diff --git a/src/render/draw.cc b/src/render/draw.cc
index 4392f87..c4c18c3 100644
--- a/src/render/draw.cc
+++ b/src/render/draw.cc
@@ -564,8 +564,9 @@ void draw_model_fragments(model::Model *model,
{
// default material, lighted and geometry color
const model::Material *material = 0;
- math::Color color(1.0f, 0.0f, 1.0f); // current drawing color
+ math::Color color(1.0f, 1.0f, 1.0f); // current drawing color
bool use_light = true; // gl::disable(GL_LIGHTING) is set
+ bool use_texture = false; // texturing
bool use_env = false; // environment mapping
//bool use_color_array = true; // glEnableClientState(GL_COLOR_ARRAY) is set
@@ -601,7 +602,7 @@ void draw_model_fragments(model::Model *model,
use_color_array = false;
}*/
- gl::color(model->enginecolor() * thrust);
+ color.assign(model->enginecolor() * thrust);
} else if (material->flags() & model::Material::Tertiary) {
/* if (use_color_array) {
@@ -648,26 +649,55 @@ void draw_model_fragments(model::Model *model,
}
}
+ if (material->flags() & model::Material::Texture) {
+
+ Textures::bind(material->texture());
+
+ if (!use_texture) {
+ gl::enable(GL_TEXTURE_2D);
+ use_texture = true;
+ }
+
+ }
+
if (material->flags() & model::Material::Environment) {
- if (!use_env && core::localplayer()->zone()->sky_texture()) {
- Textures::bind(core::localplayer()->zone()->sky_texture());
+
+ if (!(material->flags() & model::Material::Texture)) {
+ // use sky as envmap if the material defines no texture
+ if (core::localplayer()->zone()->sky_texture()) {
+ Textures::bind(core::localplayer()->zone()->sky_texture());
+ gl::enable(GL_TEXTURE_2D);
+ use_texture = true;
+ } else if (use_texture) {
+ gl::disable(GL_TEXTURE_2D);
+ use_texture = false;
+ }
+ }
+ if (!use_env) {
// enable env mapping
- gl::enable(GL_TEXTURE_2D);
gl::enable(GL_TEXTURE_GEN_S);
gl::enable(GL_TEXTURE_GEN_T);
use_env = true;
}
+
} else {
+
if (use_env) {
// disable env mapping
gl::disable(GL_TEXTURE_GEN_S);
gl::disable(GL_TEXTURE_GEN_T);
- gl::disable(GL_TEXTURE_2D);
use_env = false;
}
}
+ if (!(material->flags() & (model::Material::Texture + model::Material::Environment))) {
+ if (use_texture) {
+ gl::disable(GL_TEXTURE_2D);
+ use_texture = false;
+ }
+ }
+
} else {
// material not found
@@ -681,9 +711,14 @@ void draw_model_fragments(model::Model *model,
// disable env mapping
gl::disable(GL_TEXTURE_GEN_S);
gl::disable(GL_TEXTURE_GEN_T);
- gl::disable(GL_TEXTURE_2D);
use_env = false;
}
+
+ if (use_texture) {
+ gl::disable(GL_TEXTURE_2D);
+ use_texture = false;
+ }
+
/* if (!use_color_array) {
glEnableClientState(GL_COLOR_ARRAY);
use_color_array = true;
@@ -707,13 +742,16 @@ void draw_model_fragments(model::Model *model,
if (use_env) {
// disable env mapping
- gl::disable(GL_TEXTURE_2D);
gl::disable(GL_TEXTURE_GEN_S);
gl::disable(GL_TEXTURE_GEN_T);
-
use_env = false;
}
+ if (use_texture) {
+ gl::disable(GL_TEXTURE_2D);
+ use_texture = false;
+ }
+
/* if (!use_color_array) {
glEnableClientState(GL_COLOR_ARRAY);
}*/