Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2014-07-09 19:18:31 +0000
committerStijn Buys <ingar@osirion.org>2014-07-09 19:18:31 +0000
commit1d518a54914531d7a4fab3a6835b75de85bd7bc7 (patch)
treecabfcb6f735e3c928cddf79169fb84d9b422747f /src/model
parent25a7edee2f003f259fc3a97bbfc047d72adaa361 (diff)
Initial support for multi-layered materials, requires shaders files in the new format.
Diffstat (limited to 'src/model')
-rw-r--r--src/model/Makefile.am2
-rw-r--r--src/model/asefile.cc14
-rw-r--r--src/model/layer.cc46
-rw-r--r--src/model/layer.h96
-rw-r--r--src/model/mapfile.cc35
-rw-r--r--src/model/material.cc316
-rw-r--r--src/model/material.h199
-rw-r--r--src/model/objfile.cc25
8 files changed, 415 insertions, 318 deletions
diff --git a/src/model/Makefile.am b/src/model/Makefile.am
index cd7defd..5207d75 100644
--- a/src/model/Makefile.am
+++ b/src/model/Makefile.am
@@ -9,6 +9,7 @@ noinst_HEADERS = \
collisionmodel.h \
face.h \
fragment.h \
+ layer.h \
mapfile.h \
material.h \
model.h \
@@ -26,6 +27,7 @@ libmodel_la_SOURCES = \
collisionmodel.cc \
face.cc \
fragment.cc \
+ layer.cc \
mapfile.cc \
material.cc \
model.cc \
diff --git a/src/model/asefile.cc b/src/model/asefile.cc
index ffc0e9d..90bd6f2 100644
--- a/src/model/asefile.cc
+++ b/src/model/asefile.cc
@@ -112,12 +112,7 @@ Material *ASEFile::read_submaterial(std::istream &is)
n += c;
// find material
- material = Material::find(n);
- if (!material) {
- material = new Material(n);
- Material::add(material);
- material->set_texture(material->name());
- }
+ material = Material::load(n);
} else {
do {
@@ -187,12 +182,7 @@ ASEFile::SubMaterialList *ASEFile::read_material(std::istream &is)
if (materialname.size()) {
// no submaterials, add a single material to the submaterial list
- Material *material = Material::find(materialname);
- if (!material) {
- material = new Material(materialname);
- Material::add(material);
- material->set_texture(materialname);
- }
+ Material *material = Material::load(materialname);
(*submaterials)[0] = material;
}
diff --git a/src/model/layer.cc b/src/model/layer.cc
index 81faa6c..51d8c9a 100644
--- a/src/model/layer.cc
+++ b/src/model/layer.cc
@@ -10,12 +10,15 @@ namespace model
{
Layer::Layer() :
+ layer_size(),
layer_rgbgen(RGBGenIdentity),
- layer_color(),
+ layer_color(1.0f),
+ layer_color_specular(1.0f),
layer_texmap(TexMapNone),
layer_texture_name(),
layer_texture_id(0),
- layer_tcgen(TCGenNone)
+ layer_tcgen(TCGenBase),
+ layer_bright(false)
{
}
@@ -23,6 +26,11 @@ Layer::~Layer()
{
}
+void Layer::set_size(const math::Vector2f & size)
+{
+ layer_size.assign(size);
+}
+
void Layer::set_rgbgen(const RGBGen rgbgen)
{
layer_rgbgen = rgbgen;
@@ -32,11 +40,43 @@ void Layer::set_color(const math::Color & color)
{
layer_color.assign(color);
}
+
+void Layer::set_specular(const math::Color & specular)
+{
+ layer_color_specular.assign(specular);
+}
+
+void Layer::set_texmap(const TexMap texmap)
+{
+ layer_texmap = texmap;
+}
+
+void Layer::set_texture(const std::string & texture)
+{
+ if (texture.size())
+ {
+ layer_texture_name.assign(texture);
+ set_texmap(TexMapImage);
+ } else {
+ layer_texture_name.clear();
+ set_texmap(TexMapNone);
+ }
+}
+void Layer::set_texture_id(const size_t id)
+{
+ layer_texture_id = id;
+}
+
void Layer::set_tcgen(const TCGen tcgen)
{
layer_tcgen = tcgen;
}
-
+
+void Layer::set_bright(const bool bright)
+{
+ layer_bright = bright;
+}
+
}
diff --git a/src/model/layer.h b/src/model/layer.h
index 52ab9d8..5cc7d2b 100644
--- a/src/model/layer.h
+++ b/src/model/layer.h
@@ -1,5 +1,5 @@
/*
- model/material.h
+ model/layers.h
This file is part of the Osirion project and is distributed under
the terms of the GNU General Public License version 2
*/
@@ -7,6 +7,7 @@
#ifndef __INCLUDED_MODEL_LAYER_H__
#define __INCLUDED_MODEL_LAYER_H__
+#include "math/vector2f.h"
#include "math/color.h"
namespace model
@@ -30,15 +31,6 @@ public:
};
/**
- * @brief texture coordinate generation type definition
- * */
- enum TCGen {
- TCGenNone = 0, // no texture coordinate generation
- TCGenTexCoords = 1, // use texture coordinates from vertex array
- TCGenEnvironment = 2 // texture coordinates generated by GL_SPHERE_MAP/GL_REFLECTION_MAP
- };
-
- /**
* @brief texture map type definition
* */
enum TexMap {
@@ -47,6 +39,14 @@ public:
TexMapEnvironment = 2, // texture map with skybox
TexMapLogo = 3 // use current logo texture
};
+
+ /**
+ * @brief texture coordinate generation type definition
+ * */
+ enum TCGen {
+ TCGenBase = 1, // use texture coordinates from vertex array
+ TCGenEnvironment = 2 // texture coordinates generated by GL_SPHERE_MAP/GL_REFLECTION_MAP
+ };
/**
* @brief default constructor
@@ -59,6 +59,14 @@ public:
~Layer();
/* ---- inspectors ----------------------------------------- */
+
+ /**
+ * @brief size of the layer, in pixels
+ */
+ inline const math::Vector2f & size() const
+ {
+ return layer_size;
+ }
/**
* @brief rgb color generation source for this material layer
@@ -76,6 +84,15 @@ public:
{
return layer_color;
}
+
+ /**
+ * @brief layer specular color
+ * The specular color is used in lighting calculations.
+ * */
+ inline const math::Color & specular() const
+ {
+ return layer_color_specular;
+ }
/**
* @brief layer texture map
@@ -89,7 +106,7 @@ public:
* @brief layer texture map name
* The layer texture mapa name is used if texmap() is set to TexMapTexture
* */
- inline const std::string &texture_name() const
+ inline const std::string &texture() const
{
return layer_texture_name;
}
@@ -109,6 +126,14 @@ public:
{
return layer_tcgen;
}
+
+ /**
+ * @brief returns true if lighting calculations should be disabled for this layer
+ * */
+ inline const bool bright() const
+ {
+ return layer_bright;
+ }
/* ---- mutators ------------------------------------------- */
@@ -123,19 +148,56 @@ public:
void set_color(const math::Color & color);
/**
+ * @brief set layer specular color
+ * This value is used in lighting calculations
+ * */
+ void set_specular(const math::Color & specular);
+
+
+ /**
+ * @brief set the texture map type
+ * */
+ void set_texmap(const TexMap texmap);
+
+ /**
+ * @brief set the texture map name
+ * */
+ void set_texture(const std::string & texture);
+
+ /**
+ * @brief set the renderer texture id
+ * */
+ void set_texture_id(const size_t id);
+
+ /**
* @brief set texture coordinates generation source
* */
void set_tcgen(const TCGen tcgen);
+
+ /**
+ * @brief enable or disable lighting calculations on this layer
+ * If set to true, lighting is disabled.
+ * */
+ void set_bright(const bool bright);
+
+ /**
+ * @brief set the layer size, in pixels
+ * */
+ void set_size(const math::Vector2f & size);
private:
- RGBGen layer_rgbgen;
- math::Color layer_color;
+ math::Vector2f layer_size;
+ RGBGen layer_rgbgen;
+ math::Color layer_color;
+ math::Color layer_color_specular;
- TexMap layer_texmap;
- std::string layer_texture_name;
- size_t layer_texture_id;
+ TexMap layer_texmap;
+ std::string layer_texture_name;
+ size_t layer_texture_id;
- TCGen layer_tcgen;
+ TCGen layer_tcgen;
+
+ bool layer_bright;
};
} // namespace model
diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc
index b78448c..49122d5 100644
--- a/src/model/mapfile.cc
+++ b/src/model/mapfile.cc
@@ -382,13 +382,8 @@ bool MapFile::read_patchdef()
}
}
- // find the material for this patch
- Material *material = Material::find("textures/" + materialname);
- if (!material) {
- material = new Material("textures/" + materialname);
- Material::add(material);
- material->set_texture(material->name());
- }
+ // load the material for this patch
+ Material *material = Material::load("textures/" + materialname);
// find the primitives for the current material,
// allocate a new one if necessary
@@ -707,13 +702,7 @@ bool MapFile::getline()
linestream >> texture;
aux::to_lowercase(texture);
- Material *material = Material::find("textures/" + texture);
- if (!material) {
- material = new Material("textures/" + texture);
- Material::add(material);
- //material->set_flags(Material::Texture);
- material->set_texture(material->name());
- }
+ Material *material = Material::load("textures/" + texture);
face->set_material(material);
// texture alignment
@@ -998,12 +987,10 @@ void MapFile::make_brushface(Face *face)
Quad *quad = new Quad(*(*vn2) * SCALE, *(*vn1) * SCALE, *(*vn) * SCALE, *(*v0) * SCALE, face_normal, face->detail());
primitives->add_quad(quad);
- if (face->material()->has_flag_texture()) {
- quad->t0().assign(map_texture_coords(face, *(*vn2)));
- quad->t1().assign(map_texture_coords(face, *(*vn1)));
- quad->t2().assign(map_texture_coords(face, *(*vn)));
- quad->t3().assign(map_texture_coords(face, *(*v0)));
- }
+ quad->t0().assign(map_texture_coords(face, *(*vn2)));
+ quad->t1().assign(map_texture_coords(face, *(*vn1)));
+ quad->t2().assign(map_texture_coords(face, *(*vn)));
+ quad->t3().assign(map_texture_coords(face, *(*v0)));
delete(*vn);
delete(*vn1);
@@ -1022,11 +1009,9 @@ void MapFile::make_brushface(Face *face)
Triangle * triangle = new Triangle(*(*vn1) * SCALE, *(*vn) * SCALE, *(*v0) * SCALE, face_normal, face->detail());
primitives->add_triangle(triangle);
- if (face->material()->has_flag_texture()) {
- triangle->t0().assign(map_texture_coords(face, *(*vn1)));
- triangle->t1().assign(map_texture_coords(face, *(*vn)));
- triangle->t2().assign(map_texture_coords(face, *(*v0)));
- }
+ triangle->t0().assign(map_texture_coords(face, *(*vn1)));
+ triangle->t1().assign(map_texture_coords(face, *(*vn)));
+ triangle->t2().assign(map_texture_coords(face, *(*v0)));
delete(*vn);
vl.pop_back();
diff --git a/src/model/material.cc b/src/model/material.cc
index 29bd80e..0f3487c 100644
--- a/src/model/material.cc
+++ b/src/model/material.cc
@@ -6,69 +6,47 @@
#include <string>
+#include "model/material.h"
+
#include "auxiliary/functions.h"
#include "filesystem/filestream.h"
#include "math/functions.h"
-#include "model/material.h"
#include "sys/sys.h"
namespace model
{
-Material::LoaderFuncPtr Material::material_loaderfunc = 0;
+Material::ImageLoaderFuncPtr Material::material_imageloaderfunc = 0;
Material::Registry Material::material_registry;
Material::Material(const std::string &name) :
material_name(name),
- material_color(1.0f) ,
- material_specular(1.0f) ,
+ material_flags(0),
material_size(64.0f, 64.0f)
{
aux::to_lowercase(material_name);
- material_flags = 0;
- material_colortype = ColorMaterial;
- material_texture_id = 0;
-
}
Material::~Material()
{
+ for (Layers::iterator it = material_layers.begin(); it != material_layers.end(); ++it) {
+ delete (*it);
+ (*it) = 0;
+ }
+}
+
+void Material::set_size(const math::Vector2f & size)
+{
+ material_size.assign(size);
}
void Material::print()
{
con_print << name() << std::endl;
-
- con_print << " material color: " << material_color.r << " " << material_color.g << " " << material_color.b << " " << material_color.a << std::endl;
- switch (colortype()) {
- case ColorMaterial:
- break;
- case ColorPrimary:
- con_print << " color type " << "entity primary" << std::endl;
- break;
- case ColorSecondary:
- con_print << " color type " << "entity secondary" << std::endl;
- break;
- case ColorTertiary:
- con_print << " color type " << "entity tertiary" << std::endl;
- break;
- case ColorEngine:
- con_print << " color type " << "entity engine" << std::endl;
- break;
- }
con_print << " flags: " << flags() << " ";
if (flags() == FlagNone) {
con_print << "none";
} else {
- if (flags() & FlagBright) {
- con_print << "bright ";
- }
- if (flags() & FlagEnvironment) {
- con_print << "environment ";
- }
- if (flags() & FlagTexture) {
- con_print << "texture ";
- }
if (flags() & FlagIgnore) {
con_print << "ignore ";
}
@@ -84,61 +62,47 @@ void Material::print()
if (flags() & FlagBounds) {
con_print << "bounds ";
}
- }
- con_print << std::endl;
-
- if (material_texture.size()) {
- con_print << " texture: " << material_texture << std::endl;
}
+ con_print << " layers: " << layers().size() << std::endl;
-}
-
-void Material::set_color(const math::Color &color)
-{
- material_color.assign(color);
- //material_color.a = 1.0f;
-}
-
-void Material::set_specular(const math::Color &color)
-{
- material_specular.assign(color);
-}
-
-void Material::set_texture(const std::string &texture)
-{
- if (texture.size()) {
- set_flags(FlagTexture);
- material_texture.assign(texture);
- if (material_loaderfunc) {
- material_loaderfunc(this);
+ for (Layers::const_iterator lit = material_layers.begin(); lit != material_layers.end(); ++lit) {
+ const Layer *layer = (*lit);
+
+ con_print << " - texture: ";
+ if (layer->texmap() == Layer::TexMapNone) {
+ con_print << "none";
+ } else if (layer->texmap() == Layer::TexMapImage) {
+ con_print << layer->texture();
}
- } else {
- unset_flags(FlagTexture);
- material_texture.clear();
- material_texture_id = 0;
+ con_print << std::endl;
+
+ con_print << " color: " << layer->color() << std::endl;
+
+ con_print << " rgbgen: ";
+ switch (layer->rgbgen()) {
+ case Layer::RGBGenIdentity:
+ con_print << "identity";
+ break;
+ case Layer::RGBGenColor:
+ con_print << "color";
+ break;
+ case Layer::RGBGenEngine:
+ con_print << "engine";
+ break;
+ case Layer::RGBGenPrimary:
+ con_print << "entity primary";
+ break;
+ case Layer::RGBGenSecondary:
+ con_print << "entity secondary";
+ break;
+ case Layer::RGBGenTertiary:
+ con_print << "entity tertiary";
+ break;
+ }
+ con_print << std::endl;
}
}
-void Material::set_texture_id(const size_t texture_id)
-{
- material_texture_id = texture_id;
-}
-
-void Material::set_size(const float width, const float height)
-{
- material_size.assign(width, height);
-}
-
-void Material::set_size(const math::Vector2f &size)
-{
- material_size.assign(size);
-}
-
-void Material::set_colortype(ColorType colortype)
-{
- material_colortype = colortype;
-}
-
/* ---- static ----------------------------------------------------- */
void Material::init()
@@ -185,13 +149,6 @@ void Material::shutdown()
clear();
}
-void Material::add(Material *material)
-{
- if (!find(material->name())) {
- material_registry[material->name()] = material;
- }
-}
-
void Material::load_shaderfile(const std::string &shadername)
{
std::string shaderfilename("materials/");
@@ -209,7 +166,9 @@ void Material::load_shaderfile(const std::string &shadername)
char line[1024];
unsigned int count = 0;
float r, g, b, a;
+
Material *material = 0;
+ Layer *layer = 0;
while (shaderfile.getline(line, 1023)) {
linenumber++;
@@ -233,26 +192,77 @@ void Material::load_shaderfile(const std::string &shadername)
if (firstword.compare("//") == 0) {
continue;
- } else if (firstword.compare("}") == 0) {
+ } else if (firstword.compare("}") == 0){
+ if (parselevel == 2) {
+ // leaving layer definition
+ layer = 0;
+ } else if (parselevel == 1) {
+ // leaving material definition
+ material = 0;
+ }
parselevel--;
} else if (firstword.compare("{") == 0) {
parselevel++;
- } else if ((firstword.size()) && (parselevel == 0)) {
-
+ } else if (parselevel == 0) {
+
+ // add new material
material = find(firstword);
if (material) {
con_warn << "Duplicate material '" << firstword << "'" << std::endl;
+ material = 0;
+ layer = 0;
} else {
material = new Material(firstword);
- add(material);
+ material_registry[material->name()] = material;
count++;
- //con_debug << " " << firstword << std::endl;
+
+ layer = 0;
}
} else if ((parselevel == 1) && (material)) {
+
+ // inside material definition
+
+ aux::to_lowercase(firstword);
+
+ if (firstword.compare("qer_editorimage") == 0) {
+ // keyword qer_editorimage is ignored
+ continue;
+ } else if (firstword.compare("qer_trans") == 0) {
+ // keyword qer_trans is ignored
+ continue;
+ } else if (firstword.compare("surfaceparm") == 0) {
+ // keyword surfaceparm is ignored
+ continue;
+
+ } else if (firstword.compare("ignore") == 0) {
+ material->set_flags(FlagIgnore);
+ } else if (firstword.compare("clip") == 0) {
+ material->set_flags(FlagClip);
+ } else if (firstword.compare("origin") == 0) {
+ material->set_flags(FlagOrigin);
+ } else if (firstword.compare("decal") == 0) {
+ material->set_flags(FlagDecal);
+ } else if (firstword.compare("bounds") == 0) {
+ material->set_flags(FlagBounds);
+ } else {
+ con_warn << shaderfile.name() << " unknown material key '" << firstword << "' at line " << linenumber << std::endl;
+ }
+
+ } else if ((parselevel == 2) && (material)) {
+
+ // inside layer definition
+
+ // create new layer if required
+ if (!layer) {
+ layer = new Layer();
+ material->material_layers.push_back(layer);
+ }
+
aux::to_lowercase(firstword);
+
if (firstword.compare("color") == 0) {
if (linestream >> r >> g >> b) {
if (math::max(r, math::max(g, b)) > 1.0f) {
@@ -263,9 +273,10 @@ void Material::load_shaderfile(const std::string &shadername)
if (!(linestream >> a)) {
a = 1.0f;
}
- material->set_color(math::Color(r, g, b, a));
+ layer->set_color(math::Color(r, g, b, a));
+ layer->set_rgbgen(Layer::RGBGenColor);
// set specular too, preserving the old behavior
- material->set_specular(math::Color(r, g, b, a));
+ layer->set_specular(math::Color(r, g, b, a));
}
} else if (firstword.compare("specular") == 0) {
if (linestream >> r >> g >> b) {
@@ -277,56 +288,46 @@ void Material::load_shaderfile(const std::string &shadername)
if (!(linestream >> a)) {
a = 1.0f;
}
- material->set_specular(math::Color(r, g, b, a));
+ layer->set_specular(math::Color(r, g, b, a));
}
} else if (firstword.compare("engine") == 0) {
- material->set_colortype(ColorEngine);
+ layer->set_rgbgen(Layer::RGBGenEngine);
} else if (firstword.compare("entity") == 0) {
- material->set_colortype(ColorPrimary);
+ layer->set_rgbgen(Layer::RGBGenPrimary);
} else if (firstword.compare("entitysecond") == 0) {
- material->set_colortype(ColorSecondary);
+ layer->set_rgbgen(Layer::RGBGenSecondary);
} else if (firstword.compare("entitythird") == 0) {
- material->set_colortype(ColorTertiary);
-
+ layer->set_rgbgen(Layer::RGBGenTertiary);
} else if (firstword.compare("bright") == 0) {
- material->set_flags(FlagBright);
+ layer->set_bright(true);
} else if (firstword.compare("environment") == 0) {
- material->set_flags(FlagEnvironment);
- } else if (firstword.compare("ignore") == 0) {
- material->set_flags(FlagIgnore);
- } else if (firstword.compare("clip") == 0) {
- material->set_flags(FlagClip);
- } else if (firstword.compare("origin") == 0) {
- material->set_flags(FlagOrigin);
- } else if (firstword.compare("decal") == 0) {
- material->set_flags(FlagDecal);
- } else if (firstword.compare("bounds") == 0) {
- material->set_flags(FlagBounds);
- } else if (firstword.compare("qer_editorimage") == 0) {
- // keyword qer_editorimage is ignored
- continue;
- } else if (firstword.compare("qer_trans") == 0) {
- // keyword qer_trans is ignored
- continue;
- } else if (firstword.compare("surfaceparm") == 0) {
- // keyword surfaceparm is ignored
- continue;
- } else if (firstword.compare("texture") == 0) {
- // texture name should not contain spaces
+ layer->set_tcgen(Layer::TCGenEnvironment);
+ layer->set_texmap(Layer::TexMapEnvironment);
+ } else if (firstword.compare("map") == 0) {
+
if (linestream >> firstword) {
- // remove extension
- if (firstword[firstword.size()-4] == '.') {
- firstword.erase(firstword.size() - 4);
+ aux::to_lowercase(firstword);
+ if (firstword.compare("$environment") == 0) {
+ layer->set_texmap(Layer::TexMapEnvironment);
+ } else if (firstword.compare("$logo") == 0) {
+ layer->set_texmap(Layer::TexMapLogo);
+ } else {
+ // regular texture from image file
+ // FIXME strip extension from filename
+ layer->set_texture(firstword);
+
+ if (material_imageloaderfunc) {
+ material_imageloaderfunc(layer);
+ if ((layer->size().width() > 0) && (layer->size().height() > 0)) {
+ material->material_size.assign(layer->size());
+ }
+ }
}
- material->set_texture(firstword);
- } 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;
+ con_warn << shaderfile.name() << " unknown layer key '" << firstword << "' at line " << linenumber << std::endl;
}
+
}
}
}
@@ -346,16 +347,53 @@ void Material::list()
Material *Material::find(const std::string &name)
{
+ std::string searchstr(name);
+ aux::to_lowercase(searchstr);
+
for (Registry::iterator i = material_registry.begin(); i != material_registry.end(); ++i) {
- if ((*i).first.compare(name) == 0)
+ if ((*i).first.compare(searchstr) == 0)
return (*i).second;
}
return 0;
}
-void Material::set_loader_func(LoaderFuncPtr func)
+Material *Material::load(const std::string &name, const bool bright)
+{
+ // check if the requested material already exist
+ Material *material = find(name);
+ if (material)
+ {
+ return material;
+ }
+
+ // create a new material
+ material = new Material(name);
+
+ // create a single layer
+ Layer *layer = new Layer();
+
+ // add a texture
+ layer->set_texture(name);
+ layer->set_bright(bright);
+ if (material_imageloaderfunc) {
+ material_imageloaderfunc(layer);
+ if ((layer->size().width() > 0) && (layer->size().height() > 0)) {
+ material->material_size.assign(layer->size());
+ }
+ }
+
+ // add the new layer to the material
+ material->material_layers.push_back(layer);
+
+ // add the new material to the registry
+ material_registry[material->name()] = material;
+
+ return material;
+}
+
+void Material::set_imageloader_func(ImageLoaderFuncPtr func)
{
- material_loaderfunc = func;
+ material_imageloaderfunc = func;
}
}
diff --git a/src/model/material.h b/src/model/material.h
index e2a1276..2e3a696 100644
--- a/src/model/material.h
+++ b/src/model/material.h
@@ -7,12 +7,12 @@
#ifndef __INCLUDED_MODEL_MATERIAL_H__
#define __INCLUDED_MODEL_MATERIAL_H__
+#include "model/layer.h"
+
#include <string>
+#include <list>
#include <map>
-#include "math/color.h"
-#include "math/vector2f.h"
-
namespace model
{
@@ -20,17 +20,33 @@ namespace model
class Material
{
public:
- /// function pointer type for local functions
- typedef void(* LoaderFuncPtr)(Material *);
-
- /// color types
- enum ColorType {ColorMaterial = 0, ColorPrimary = 1, ColorSecondary = 2, ColorTertiary = 3, ColorEngine = 4 };
+ /**
+ * @brief function pointer type the image loader hook
+ * */
+ typedef void(* ImageLoaderFuncPtr)(Layer *);
- /// surface flags
- enum SurfaceFlags { FlagNone = 0, FlagBright = 1,FlagEnvironment = 2, FlagTexture = 4, FlagIgnore = 8, FlagClip = 16, FlagOrigin = 32, FlagDecal = 64, FlagBounds = 128 };
-
- /// type definition for the material registry
+ /**
+ * @brief type definition for the material registry
+ * */
typedef std::map<std::string, Material *> Registry;
+
+ /**
+ * @brief type definition for the material layers list
+ * */
+ typedef std::list<Layer *> Layers;
+
+ /**
+ * @brief material surface flags
+ * */
+ enum SurfaceFlags
+ {
+ FlagNone = 0,
+ FlagIgnore = 1,
+ FlagClip = 2,
+ FlagOrigin = 4,
+ FlagDecal = 8,
+ FlagBounds = 16
+ };
Material(const std::string &name);
@@ -40,61 +56,44 @@ public:
/* ---- inspectors ----------------------------------------- */
- inline const std::string &name() const {
+ /**
+ * @brief returns the name of the material
+ * */
+ inline const std::string &name() const
+ {
return material_name;
}
- inline const math::Color &color() const {
- return material_color;
- }
-
- inline const math::Color &specular() const {
- return material_specular;
- }
-
- inline const unsigned int flags() const {
- return material_flags;
- }
-
- inline const ColorType colortype() const {
- return material_colortype;
- }
-
- inline const std::string &texture() const {
- return material_texture;
- }
-
- inline const size_t texture_id() const {
- return material_texture_id;
- }
-
/**
- * @brief returns the material texture pixel size
+ * @brief returns the size of the material, in pixels
*/
- inline const math::Vector2f & size() const {
+ inline const math::Vector2f & size() const
+ {
return material_size;
}
-
+
/**
- * @brief returns true if the material has the requested flag set
+ * @brief return the flags for this material
+ * @see Flags
* */
- inline bool has_flag(const SurfaceFlags surfaceflag) const {
- return (((int) material_flags & surfaceflag) == surfaceflag);
+ inline const int flags() const
+ {
+ return material_flags;
}
-
+
/**
- * @brief returns true if the material has the Texture flag set
- * @see flags()
+ * @brief returns true if the material has the requested flag set
* */
- inline bool has_flag_texture() const {
- return (has_flag(FlagTexture));
+ inline bool has_flag(const SurfaceFlags surfaceflag) const {
+ return ((material_flags & surfaceflag) == surfaceflag);
}
/**
* @brief returns true if the material has the Clip flag set
* @see flags()
* */
- inline bool has_flag_clip() const {
+ inline bool has_flag_clip() const
+ {
return (has_flag(FlagClip));
}
@@ -102,7 +101,8 @@ public:
* @brief returns true if the material has the Ignore flag set
* @see flags()
* */
- inline bool has_flag_ignore() const {
+ inline bool has_flag_ignore() const
+ {
return (has_flag(FlagIgnore));
}
@@ -110,54 +110,28 @@ public:
* @brief returns true if the material has the Origin flag set
* @see flags()
* */
- inline bool has_flag_origin() const {
+ inline bool has_flag_origin() const
+ {
return (has_flag(FlagOrigin));
}
/**
- * @brief returns true if the material has the Origin flag set
+ * @brief returns true if the material has the Bounds flag set
* @see flags()
* */
- inline bool has_flag_bounds() const {
+ inline bool has_flag_bounds() const
+ {
return (has_flag(FlagBounds));
}
/* ---- mutators ------------------------------------------- */
-
- void set_color(const math::Color &color);
-
- void set_specular(const math::Color &specular);
-
- /**
- * @brief set the material texture name
- */
- void set_texture(const std::string &texture);
-
- /**
- * @brief set the material texture id
- */
- void set_texture_id(const size_t texture_id);
-
- /**
- * @brief set the material texture size
- */
- void set_size(const float width, const float height);
-
- /**
- * @brief set the material texture size
- */
- void set_size(const math::Vector2f &size);
-
- /**
- * @brief set the color type
- * */
- void set_colortype(ColorType colortype);
/**
* @brief set a specified surface flag
* @see flags()
* */
- inline void set_flags(SurfaceFlags flags) {
+ inline void set_flags(const SurfaceFlags flags)
+ {
material_flags |= flags;
}
@@ -165,11 +139,32 @@ public:
* @brief clear a specified surface flag
* @see flags()
* */
- inline void unset_flags(SurfaceFlags flags) {
+ inline void unset_flags(const SurfaceFlags flags)
+ {
material_flags &= ~flags;
}
+
+ void set_size(const math::Vector2f & size);
+
+ /**
+ * @brief layers in this material
+ * */
+ inline const Layers & layers() const
+ {
+ return material_layers;
+ }
+
+ inline Layers & layers()
+ {
+ return material_layers;
+ }
/* ---- static ----------------------------------------------------- */
+
+ static inline Registry registry()
+ {
+ return material_registry;
+ }
/**
* @brief initialize material registry
@@ -193,36 +188,30 @@ public:
static void list();
/**
- * @brief add a material to the registry
+ * @brief load a material into the registry
+ * If a material with the requested name already exists, it will be returned.
+ * If it doesnt, a mew material will be created, containing a single layer
+ * with a texture with the same name as the material.
*/
- static void add(Material *material);
-
+ static Material *load(const std::string &name, const bool bright=false);
+
/**
* @brief find a material in the registry
*/
static Material *find(const std::string &name);
- static void set_loader_func(LoaderFuncPtr func);
+ static void set_imageloader_func(ImageLoaderFuncPtr func);
private:
-
- std::string material_name;
- math::Color material_color;
- math::Color material_specular;
- unsigned int material_flags;
- ColorType material_colortype;
- std::string material_texture;
- size_t material_texture_id;
-
- /// size of the material
- math::Vector2f material_size;
-
- /// the materials registry
- static Registry material_registry;
-
+ Layers material_layers;
+ std::string material_name;
+ int material_flags;
+ math::Vector2f material_size;
+
+ static Registry material_registry;
+ static ImageLoaderFuncPtr material_imageloaderfunc;
+
static void load_shaderfile(const std::string &shadername);
-
- static LoaderFuncPtr material_loaderfunc;
};
}
diff --git a/src/model/objfile.cc b/src/model/objfile.cc
index 489da2c..e4cec92 100644
--- a/src/model/objfile.cc
+++ b/src/model/objfile.cc
@@ -93,7 +93,7 @@ bool OBJFile::read()
std::string materialname;
material = 0;
- if(line >> materialname) {
+ if (line >> materialname) {
for(MaterialList::iterator it = obj_materiallist.begin(); it != obj_materiallist.end(); ++it) {
if( (*it).second->name() == materialname) {
material = (*it).second;
@@ -102,18 +102,9 @@ bool OBJFile::read()
}
}
- if(!material) {
- material = Material::find(materialname);
-
- if(material)
- obj_materiallist[obj_materiallist.size()] = material;
- else {
- material = new Material(materialname);
- Material::add(material);
- material->set_texture(materialname);
-
- obj_materiallist[obj_materiallist.size()] = material;
- }
+ if (!material) {
+ material = Material::load(materialname);
+ obj_materiallist[obj_materiallist.size()] = material;
current_m = obj_materiallist.size()-1;
}
}
@@ -121,7 +112,7 @@ bool OBJFile::read()
con_warn << objfile_name << " invalid material definition at line " << index_line << std::endl;
- } else if( word.compare("v") == 0) { /* new wertex */
+ } else if (word.compare("v") == 0) { /* new wertex */
float x, y, z;
line >> x >> y >> z;
@@ -129,14 +120,14 @@ bool OBJFile::read()
obj_vertexlist[obj_vertexlist.size()] = v;
obj_box.expand(*v * SCALE);
- } else if( word.compare("vt") == 0) { /* wertex texture coordinate */
+ } else if (word.compare("vt") == 0) { /* wertex texture coordinate */
float u, v;
line >> u >> v;
math::Vector2f *uv = new math::Vector2f(u, v);
obj_uvlist[obj_uvlist.size()] = uv;
- } else if( word.compare("vn") == 0) { /* wertex wormal */
+ } else if (word.compare("vn") == 0) { /* wertex wormal */
float x, y, z;
line >> x >> y >> z;
@@ -145,7 +136,7 @@ bool OBJFile::read()
obj_normallist[obj_normalcount] = nm;
obj_normalcount++;
- } else if( word.compare("f") == 0) { /* face/polygon */
+ } else if (word.compare("f") == 0) { /* face/polygon */
size_t v[4];
size_t uv[4];
size_t vn[4];