diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/savegamemenu.cc | 38 | ||||
-rw-r--r-- | src/model/Makefile.am | 2 | ||||
-rw-r--r-- | src/model/asefile.cc | 14 | ||||
-rw-r--r-- | src/model/layer.cc | 46 | ||||
-rw-r--r-- | src/model/layer.h | 96 | ||||
-rw-r--r-- | src/model/mapfile.cc | 35 | ||||
-rw-r--r-- | src/model/material.cc | 316 | ||||
-rw-r--r-- | src/model/material.h | 199 | ||||
-rw-r--r-- | src/model/objfile.cc | 25 | ||||
-rw-r--r-- | src/render/draw.cc | 11 | ||||
-rw-r--r-- | src/render/state.cc | 133 | ||||
-rw-r--r-- | src/render/state.h | 42 | ||||
-rw-r--r-- | src/render/textures.cc | 19 | ||||
-rw-r--r-- | src/render/textures.h | 4 | ||||
-rw-r--r-- | src/ui/paint.cc | 119 |
15 files changed, 608 insertions, 491 deletions
diff --git a/src/client/savegamemenu.cc b/src/client/savegamemenu.cc index 8efd746..78cf56f 100644 --- a/src/client/savegamemenu.cc +++ b/src/client/savegamemenu.cc @@ -218,7 +218,7 @@ void SaveGameMenu::refresh() listitem->set_label("new"); listitem->set_sortkey("[new]"); listitem->set_font(ui::root()->font_tiny()); - listitem->set_height(listitem->font()->height() * 2.0f); + listitem->set_height(listitem->font()->height() * 3.0f); savegamemenu_savebutton->set_text("Save"); if (!core::localcontrol()) { @@ -275,10 +275,17 @@ void SaveGameMenu::hide() Window::hide(); model::Material *screenshotmaterial = model::Material::find("ui/screenshot"); - if (screenshotmaterial && screenshotmaterial->texture().size()) { - render::Textures::unload(screenshotmaterial->texture()); - screenshotmaterial->set_texture(""); + if (screenshotmaterial) { + for (model::Material::Layers::const_iterator lit = screenshotmaterial->layers().begin(); lit != screenshotmaterial->layers().end(); ++lit) { + if ((*lit)->texture().size()) { + render::Textures::unload((*lit)->texture()); + (*lit)->set_texture(""); + } + } + } + + savegamemenu_screenshot->set_texture(""); } void SaveGameMenu::show() @@ -323,15 +330,26 @@ void SaveGameMenu::show_file_info() model::Material *screenshotmaterial = model::Material::find("ui/screenshot"); if (!screenshotmaterial) { screenshotmaterial = new model::Material("ui/screenshot"); - model::Material::add(screenshotmaterial); - screenshotmaterial ->set_flags(model::Material::FlagTexture); - screenshotmaterial ->set_flags(model::Material::FlagBright); - } else if (screenshotmaterial->texture().size()) { - render::Textures::unload(screenshotmaterial->texture()); + model::Material::registry()["ui/screenshot"] = screenshotmaterial; + } + + model::Layer *screenshotlayer = 0; + if (screenshotmaterial->layers().size() > 0) { + screenshotlayer = (*screenshotmaterial->layers().begin()); + } else { + screenshotlayer = new model::Layer(); + screenshotmaterial->layers().push_back(screenshotlayer); + screenshotlayer->set_bright(true); + } + if (screenshotlayer->texture().size()) { + render::Textures::unload(screenshotlayer->texture()); + screenshotlayer->set_texture(""); } std::string screenshotfilename("savegames/" + savename); - screenshotmaterial->set_texture(screenshotfilename); + screenshotlayer->set_texture(screenshotfilename); + render::Textures::image_loader(screenshotlayer); + screenshotmaterial->set_size(screenshotlayer->size()); savegamemenu_screenshot->set_texture("ui/screenshot"); savegamemenu_screenshot->show(); 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]; diff --git a/src/render/draw.cc b/src/render/draw.cc index b956c18..d932739 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -736,21 +736,24 @@ void draw_model_fragments(model::Model *model, for (model::FragmentGroup::Fragments::const_iterator fit = group->fragments().begin(); fit != group->fragments().end(); fit++) { const model::Fragment *fragment = (*fit); - State::use_material(fragment->material()); - draw_fragment(fragment, detail); + + for (model::Material::Layers::const_iterator lit = fragment->material()->layers().begin(); lit != fragment->material()->layers().end(); ++lit) { + State::use_material_layer(fragment->material(), (*lit)); + draw_fragment(fragment, detail); + State::reset(); + } if (r_normals->value()) { // force reset of material settings for the next fragment State::reset(); gl::color(0.75f, 0.0f, 0.0f); draw_fragment_normals(fragment, detail); + State::reset(); } } gl::pop(); } - - State::reset(); } // draw entity axis diff --git a/src/render/state.cc b/src/render/state.cc index 400a186..7857963 100644 --- a/src/render/state.cc +++ b/src/render/state.cc @@ -24,6 +24,7 @@ bool State::state_has_vbo = false; GLuint State::state_vbo = 0; int State::state_maxlights; int State::state_maxtextureunits; +size_t State::state_logo_texture_id = 0; math::Color State::state_color_primary; @@ -191,8 +192,6 @@ void State::set_normalize(const bool enable) } } - - void State::set_color(const math::Color & color) { state_color_primary.assign(color); @@ -218,24 +217,14 @@ void State::set_power(const bool power) state_power = power; } -void State::use_material(const model::Material * material) { - - math::Color color; - math::Color specular; - - reset(); - - // default specular shininess setting - gl::material(GL_FRONT, GL_SHININESS, 8); - - if (!material) { - color.assign(1.0f, 0.0f, 1.0f); - specular.assign(1.0f, 0.0f, 1.0f); - gl::color(color); - gl::specular(specular); +void State::use_material_layer(const model::Material * material, const model::Layer *layer) +{ + if (!material || !layer) { + gl::color(math::Color(1.0f, 0.0f, 1.0f)); + gl::specular(math::Color(1.0f, 0.0f, 1.0f)); return; } - + // material has the decal flag set if (material->has_flag(model::Material::FlagDecal)) { gl::enable(GL_POLYGON_OFFSET_FILL); @@ -244,32 +233,36 @@ void State::use_material(const model::Material * material) { gl::alphafunc(GL_GEQUAL, 0.5f); } - // assign the opengl drawing color according to material flags - switch (material->colortype()) { - case model::Material::ColorMaterial: - color.assign(material->color()); - specular.assign(material->specular()); + math::Color color(layer->color()); + math::Color specular(layer->color()); + + // apply color generation rules + switch (layer->rgbgen()) { + case model::Layer::RGBGenIdentity: break; - case model::Material::ColorEngine: + case model::Layer::RGBGenColor: + break; + + case model::Layer::RGBGenEngine: // assign current engine color color.assign(state_color_engine); specular.assign(0.0f); break; - case model::Material::ColorPrimary: + case model::Layer::RGBGenPrimary: // assign current primary entity color color.assign(state_color_primary); specular.assign(state_color_primary); break; - case model::Material::ColorSecondary: + case model::Layer::RGBGenSecondary: // assign current secondry entity color color.assign(state_color_secondary); specular.assign(state_color_secondary); break; - case model::Material::ColorTertiary: + case model::Layer::RGBGenTertiary: // assign current tertiary entity color for (size_t i = 0; i < 3; i++) { color[i] = (state_color_primary[i] + state_color_secondary[i]) / 2; @@ -278,66 +271,71 @@ void State::use_material(const model::Material * material) { break; } - // blend color type with material color - if (material->colortype() != model::Material::ColorMaterial) { - color.r *= material->color().r; - color.g *= material->color().g; - color.b *= material->color().b; - specular.r *= material->specular().r; - specular.g *= material->specular().g; - specular.b *= material->specular().b; + // blend current color with layer color + if ((layer->rgbgen() != model::Layer::RGBGenIdentity) && (layer->rgbgen() != model::Layer::RGBGenColor)) { + color.r *= layer->color().r; + color.g *= layer->color().g; + color.b *= layer->color().b; + specular.r *= layer->specular().r; + specular.g *= layer->specular().g; + specular.b *= layer->specular().b; } - + + gl::color(color); + gl::specular(specular); + // lighted or fullbright - if (state_power && (material->has_flag(model::Material::FlagBright))) { + if (state_power && layer->bright()) { gl::disable(GL_LIGHTING); - } else if (state_power && (material->colortype() == model::Material::ColorEngine)) { + } else if (state_power && (layer->rgbgen() == model::Layer::RGBGenEngine)) { gl::disable(GL_LIGHTING); } else { gl::enable(GL_LIGHTING); } - // texture - if (material->has_flag(model::Material::FlagTexture)) { - - Textures::bind(material->texture_id()); + // texture map + if (layer->texmap() == model::Layer::TexMapImage) { + + // map a texture image + Textures::bind(layer->texture_id()); gl::enable(GL_TEXTURE_2D); - if (material->has_flag(model::Material::FlagEnvironment)) { + // texture coordinate generation + if (layer->tcgen() == model::Layer::TCGenEnvironment) { gl::texgen(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); gl::texgen(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); gl::enable(GL_TEXTURE_GEN_S); - gl::enable(GL_TEXTURE_GEN_T); + gl::enable(GL_TEXTURE_GEN_T); } - - } else { - // envmapped without texture: use the skybox as envmap - if (material->has_flag(model::Material::FlagEnvironment)) { - if (core::localplayer()->zone()->sky().size()) { - gl::enable(GL_TEXTURE_CUBE_MAP); + + } else if (layer->texmap() == model::Layer::TexMapEnvironment) { + + // map the current skybox + + if (core::localplayer()->zone()->sky().size()) { + gl::enable(GL_TEXTURE_CUBE_MAP); - gl::texgen(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - gl::texgen(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - gl::texgen(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + gl::texgen(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + gl::texgen(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + gl::texgen(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); - gl::enable(GL_TEXTURE_GEN_S); - gl::enable(GL_TEXTURE_GEN_T); - gl::enable(GL_TEXTURE_GEN_R); - } else { - color.assign(0.0f, 0.0f, 0.0f); - } - gl::material(GL_FRONT, GL_SHININESS, 4); + gl::enable(GL_TEXTURE_GEN_S); + gl::enable(GL_TEXTURE_GEN_T); + gl::enable(GL_TEXTURE_GEN_R); + } else { + color.assign(0.0f, 0.0f, 0.0f); } + gl::material(GL_FRONT, GL_SHININESS, 4); + } - - gl::color(color); - gl::specular(specular); + } -void State::reset() { +void State::reset() +{ gl::disable(GL_POLYGON_OFFSET_FILL); gl::disable(GL_ALPHA_TEST); gl::disable(GL_TEXTURE_GEN_S); @@ -346,7 +344,12 @@ void State::reset() { gl::disable(GL_LIGHTING); gl::disable(GL_TEXTURE_CUBE_MAP); gl::disable(GL_TEXTURE_2D); - gl::color(1.0f, 1.0f, 1.0f, 1.0f); + + // default specular shininess setting + gl::material(GL_FRONT, GL_SHININESS, 8); + + gl::color(math::Color(1.0f)); + gl::specular(math::Color(0.0f)); } } // namespace render diff --git a/src/render/state.h b/src/render/state.h index ea55602..0581c2e 100644 --- a/src/render/state.h +++ b/src/render/state.h @@ -75,36 +75,51 @@ public: static void set_power(const bool power); /** - * @brief Set the material context - * use_material() will alter the current render context according to the settings - * defined by the material. If the material uses primary, secondary or engine color, - * the current material context colors will be used. + * @brief set the material layer context + * use_material_layer() will alter the current render context according to the settings + * defined by the material layer. If the material uses primary, secondary or engine color, + * the current state context colors will be used. **/ - static void use_material(const model::Material * material); + static void use_material_layer(const model::Material * material, const model::Layer *layer); - inline static int width() { + inline static int width() + { return state_width; } - inline static int height() { + + inline static int height() + { return state_height; } - inline static float aspect() { + + inline static float aspect() + { return state_aspect; } - inline static bool has_generate_mipmaps() { + + inline static bool has_generate_mipmaps() + { return state_has_generate_mipmaps; } - inline static bool has_vbo() { + + inline static bool has_vbo() + { return state_has_vbo; } - inline static GLuint vbo() { + + inline static GLuint vbo() + { return state_vbo; } - inline static int max_lights() { + + inline static int max_lights() + { return state_maxlights; } - inline static int max_textureunits() { + + inline static int max_textureunits() + { return state_maxtextureunits; } @@ -120,6 +135,7 @@ private: static GLuint state_vbo; static int state_maxlights; static int state_maxtextureunits; + static size_t state_logo_texture_id; static math::Color state_color_primary; // current primary color static math::Color state_color_secondary; // current secondary color diff --git a/src/render/textures.cc b/src/render/textures.cc index 5a90640..bd75a45 100644 --- a/src/render/textures.cc +++ b/src/render/textures.cc @@ -24,11 +24,6 @@ GLuint Textures::textures_cubemap_id; math::Vector2f Textures::texture_size[MAXTEXTURES]; std::string textures_cubemapname; -void material_loader_func(model::Material *material) -{ - Textures::material_loader(material); -} - void Textures::init() { con_print << "^BLoading textures..." << std::endl; @@ -57,12 +52,12 @@ void Textures::init() load("bitmaps/pointers/control"); load("bitmaps/pointers/target"); - model::Material::set_loader_func(Textures::material_loader); + model::Material::set_imageloader_func(Textures::image_loader); } void Textures::shutdown() { - model::Material::set_loader_func(0); + model::Material::set_imageloader_func(0); clear(); } @@ -416,12 +411,12 @@ size_t Textures::bind(const size_t texture, const bool filter) return id; } -void Textures::material_loader(model::Material *material) +void Textures::image_loader(model::Layer *layer) { - if (material->has_flag(model::Material::FlagTexture) && (material->texture().size() > 0)) { - size_t id = load(material->texture()); - material->set_texture_id(id); - material->set_size(texture_size[id]); + if (layer->texture().size() > 0 ) { + size_t id = load(layer->texture()); + layer->set_texture_id(id); + layer->set_size(texture_size[id]); } } diff --git a/src/render/textures.h b/src/render/textures.h index 69442e8..2341672 100644 --- a/src/render/textures.h +++ b/src/render/textures.h @@ -60,8 +60,8 @@ public: /// list loaded textures static void list(); - /// material loader func - static void material_loader(model::Material *material); + /// material image loader hook + static void image_loader(model::Layer *layer); private: static void clear(); diff --git a/src/ui/paint.cc b/src/ui/paint.cc index cea363c..d33e1a3 100644 --- a/src/ui/paint.cc +++ b/src/ui/paint.cc @@ -76,15 +76,7 @@ void Paint::draw_rectangle_gradient(const math::Vector2f &global_location, const void Paint::draw_bitmap(const math::Vector2f &global_location, const math::Vector2f &size, const std::string &texture, const float preserve_aspect) { - // find the material - model::Material *material = model::Material::find(texture); - if (!material) { - material = new model::Material(texture); - model::Material::add(material); - material->set_texture(material->name()); - // ui btimaps are fullbright - material->set_flags(model::Material::FlagBright); - } + model::Material *material = model::Material::load(texture, true); math::Vector2f bitmap_location; math::Vector2f bitmap_size(size); @@ -101,39 +93,34 @@ void Paint::draw_bitmap(const math::Vector2f &global_location, const math::Vecto render::State::set_color(math::Color()); render::State::set_color_second(math::Color()); - render::State::use_material(material); - gl::begin(gl::Quads); - - glTexCoord2f(0.0f, 0.0f); - gl::vertex(bitmap_location.x(), bitmap_location.y()); + for (model::Material::Layers::const_iterator lit = material->layers().begin(); lit != material->layers().end(); ++lit) { + render::State::use_material_layer(material, *lit); + + gl::begin(gl::Quads); - glTexCoord2f(1.0f, 0.0f); - gl::vertex(bitmap_location.x() + bitmap_size.width(), bitmap_location.y()); + glTexCoord2f(0.0f, 0.0f); + gl::vertex(bitmap_location.x(), bitmap_location.y()); - glTexCoord2f(1.0f, 1.0f); - gl::vertex(bitmap_location.x() + bitmap_size.width(), bitmap_location.y() + bitmap_size.height()); + glTexCoord2f(1.0f, 0.0f); + gl::vertex(bitmap_location.x() + bitmap_size.width(), bitmap_location.y()); - glTexCoord2f(0.0f, 1.0f); - gl::vertex(bitmap_location.x(), bitmap_location.y() + bitmap_size.height()); + glTexCoord2f(1.0f, 1.0f); + gl::vertex(bitmap_location.x() + bitmap_size.width(), bitmap_location.y() + bitmap_size.height()); - gl::end(); + glTexCoord2f(0.0f, 1.0f); + gl::vertex(bitmap_location.x(), bitmap_location.y() + bitmap_size.height()); + gl::end(); + } + render::State::reset(); } // draw a bitmap and override material color void Paint::draw_bitmap(const math::Vector2f &global_location, const math::Vector2f &size, const math::Color & color, const std::string &texture, const float preserve_aspect) { - // find the material - model::Material *material = model::Material::find(texture); - if (!material) { - material = new model::Material(texture); - model::Material::add(material); - material->set_texture(material->name()); - // ui btimaps are fullbright - material->set_flags(model::Material::FlagBright); - } + model::Material *material = model::Material::load(texture, true); math::Vector2f bitmap_location; math::Vector2f bitmap_size(size); @@ -148,41 +135,36 @@ void Paint::draw_bitmap(const math::Vector2f &global_location, const math::Vecto } render::State::set_power(true); - render::State::use_material(material); - // this overrides material color - gl::color(color); - gl::begin(gl::Quads); + for (model::Material::Layers::const_iterator lit = material->layers().begin(); lit != material->layers().end(); ++lit) { + render::State::use_material_layer(material, *lit); + + // this overrides material color + gl::color(color); + + gl::begin(gl::Quads); - glTexCoord2f(0.0f, 0.0f); - gl::vertex(bitmap_location.x(), bitmap_location.y()); + glTexCoord2f(0.0f, 0.0f); + gl::vertex(bitmap_location.x(), bitmap_location.y()); - glTexCoord2f(1.0f, 0.0f); - gl::vertex(bitmap_location.x() + bitmap_size.width(), bitmap_location.y()); + glTexCoord2f(1.0f, 0.0f); + gl::vertex(bitmap_location.x() + bitmap_size.width(), bitmap_location.y()); - glTexCoord2f(1.0f, 1.0f); - gl::vertex(bitmap_location.x() + bitmap_size.width(), bitmap_location.y() + bitmap_size.height()); + glTexCoord2f(1.0f, 1.0f); + gl::vertex(bitmap_location.x() + bitmap_size.width(), bitmap_location.y() + bitmap_size.height()); - glTexCoord2f(0.0f, 1.0f); - gl::vertex(bitmap_location.x(), bitmap_location.y() + bitmap_size.height()); + glTexCoord2f(0.0f, 1.0f); + gl::vertex(bitmap_location.x(), bitmap_location.y() + bitmap_size.height()); - gl::end(); - - render::State::reset(); + gl::end(); + render::State::reset(); + } } void Paint::draw_material(const math::Vector2f &global_location, const math::Vector2f &size, const std::string &texture) { - // find the material - model::Material *material = model::Material::find(texture); - if (!material) { - material = new model::Material(texture); - model::Material::add(material); - material->set_texture(material->name()); - // ui btimaps are fullbright - material->set_flags(model::Material::FlagBright); - } + model::Material *material = model::Material::load(texture, true); // use global coordinates const float w0 = global_location.x() / material->size().width(); @@ -194,25 +176,28 @@ void Paint::draw_material(const math::Vector2f &global_location, const math::Vec render::State::set_power(true); render::State::set_color(math::Color()); render::State::set_color_second(math::Color()); - render::State::use_material(material); - gl::begin(gl::Quads); - - glTexCoord2f(w0, h0); - gl::vertex(global_location.x(), global_location.y()); + + for (model::Material::Layers::const_iterator lit = material->layers().begin(); lit != material->layers().end(); ++lit) { + render::State::use_material_layer(material, *lit); + + gl::begin(gl::Quads); - glTexCoord2f(w1, h0); - gl::vertex(global_location.x() + size.width(), global_location.y()); + glTexCoord2f(w0, h0); + gl::vertex(global_location.x(), global_location.y()); - glTexCoord2f(w1, h1); - gl::vertex(global_location.x() + size.width(), global_location.y() + size.height()); + glTexCoord2f(w1, h0); + gl::vertex(global_location.x() + size.width(), global_location.y()); - glTexCoord2f(w0, h1); - gl::vertex(global_location.x(), global_location.y() + size.height()); + glTexCoord2f(w1, h1); + gl::vertex(global_location.x() + size.width(), global_location.y() + size.height()); - gl::end(); + glTexCoord2f(w0, h1); + gl::vertex(global_location.x(), global_location.y() + size.height()); - render::State::reset(); + gl::end(); + render::State::reset(); + } } // draw unaligned text |