From 1d518a54914531d7a4fab3a6835b75de85bd7bc7 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 9 Jul 2014 19:18:31 +0000 Subject: Initial support for multi-layered materials, requires shaders files in the new format. --- src/model/Makefile.am | 2 + src/model/asefile.cc | 14 +-- src/model/layer.cc | 46 +++++++- src/model/layer.h | 96 ++++++++++++--- src/model/mapfile.cc | 35 ++---- src/model/material.cc | 316 ++++++++++++++++++++++++++++---------------------- src/model/material.h | 199 +++++++++++++++---------------- src/model/objfile.cc | 25 ++-- 8 files changed, 415 insertions(+), 318 deletions(-) (limited to 'src/model') 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 @@ -29,15 +30,6 @@ public: RGBGenTertiary = 6 // modified by tertiary entity color }; - /** - * @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 * */ @@ -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 ------------------------------------------- */ @@ -122,20 +147,57 @@ 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 +#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 +#include #include -#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 Registry; + + /** + * @brief type definition for the material layers list + * */ + typedef std::list 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]; -- cgit v1.2.3