From d95f18442ea216a886bfddf75d349362d1e537bc Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Fri, 11 Jul 2014 19:37:17 +0000 Subject: Support material layer blending. --- src/model/layer.cc | 12 ++++++++--- src/model/layer.h | 36 ++++++++++++++++++++++++-------- src/model/material.cc | 57 +++++++++++++++++++++++++++++++++++++++++++-------- src/model/material.h | 9 +++++++- 4 files changed, 93 insertions(+), 21 deletions(-) (limited to 'src/model') diff --git a/src/model/layer.cc b/src/model/layer.cc index 51d8c9a..4ef7fbf 100644 --- a/src/model/layer.cc +++ b/src/model/layer.cc @@ -18,7 +18,8 @@ Layer::Layer() : layer_texture_name(), layer_texture_id(0), layer_tcgen(TCGenBase), - layer_bright(false) + layer_fullbright(false), + layer_blendfunc(BlendFuncNone) { } @@ -73,9 +74,14 @@ void Layer::set_tcgen(const TCGen tcgen) layer_tcgen = tcgen; } -void Layer::set_bright(const bool bright) +void Layer::set_fullbright(const bool fullbright) { - layer_bright = bright; + layer_fullbright = fullbright; +} + +void Layer::set_blendfunc(const BlendFunc blendfunc) +{ + layer_blendfunc = blendfunc; } } diff --git a/src/model/layer.h b/src/model/layer.h index 5cc7d2b..d6af529 100644 --- a/src/model/layer.h +++ b/src/model/layer.h @@ -47,6 +47,15 @@ public: TCGenBase = 1, // use texture coordinates from vertex array TCGenEnvironment = 2 // texture coordinates generated by GL_SPHERE_MAP/GL_REFLECTION_MAP }; + + /** + * @brief blend functions definition + * */ + enum BlendFunc { + BlendFuncNone = 0, // no blending + BlendFuncAdd = 1, // GL_ONE GL_OME + BlendFuncBlend = 2 // GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA + }; /** * @brief default constructor @@ -130,9 +139,17 @@ public: /** * @brief returns true if lighting calculations should be disabled for this layer * */ - inline const bool bright() const + inline const bool fullbright() const + { + return layer_fullbright; + } + + /** + * @brief returns the current alpha blending function + * */ + inline const BlendFunc blendfunc() const { - return layer_bright; + return layer_blendfunc; } /* ---- mutators ------------------------------------------- */ @@ -153,7 +170,6 @@ public: * */ void set_specular(const math::Color & specular); - /** * @brief set the texture map type * */ @@ -178,26 +194,30 @@ public: * @brief enable or disable lighting calculations on this layer * If set to true, lighting is disabled. * */ - void set_bright(const bool bright); + void set_fullbright(const bool fullbright); /** * @brief set the layer size, in pixels * */ void set_size(const math::Vector2f & size); + + /** + * @brief set alpha blending function + * */ + void set_blendfunc(const BlendFunc blendfunc); private: math::Vector2f layer_size; RGBGen layer_rgbgen; math::Color layer_color; - math::Color layer_color_specular; - + math::Color layer_color_specular; TexMap layer_texmap; std::string layer_texture_name; size_t layer_texture_id; - TCGen layer_tcgen; + bool layer_fullbright; + BlendFunc layer_blendfunc; - bool layer_bright; }; } // namespace model diff --git a/src/model/material.cc b/src/model/material.cc index 0f3487c..d4accc8 100644 --- a/src/model/material.cc +++ b/src/model/material.cc @@ -63,12 +63,16 @@ void Material::print() con_print << "bounds "; } } - con_print << " layers: " << layers().size() << std::endl; + + int count = 0; for (Layers::const_iterator lit = material_layers.begin(); lit != material_layers.end(); ++lit) { const Layer *layer = (*lit); - con_print << " - texture: "; + count++; + con_print << " layer " << count << std::endl; + + con_print << " texture: "; if (layer->texmap() == Layer::TexMapNone) { con_print << "none"; } else if (layer->texmap() == Layer::TexMapImage) { @@ -76,9 +80,9 @@ void Material::print() } con_print << std::endl; - con_print << " color: " << layer->color() << std::endl; + con_print << " color: " << layer->color() << std::endl; - con_print << " rgbgen: "; + con_print << " rgbgen: "; switch (layer->rgbgen()) { case Layer::RGBGenIdentity: con_print << "identity"; @@ -100,6 +104,21 @@ void Material::print() break; } con_print << std::endl; + + if (layer->fullbright()) { + con_print << " fullbright" << std::endl; + } + + switch(layer->blendfunc()) { + case Layer::BlendFuncNone: + break; + case Layer::BlendFuncAdd: + con_print << " blendfunc: add" << std::endl; + break; + case Layer::BlendFuncBlend: + con_print << " blendfunc: blend" << std::endl; + break; + } } } @@ -298,11 +317,26 @@ void Material::load_shaderfile(const std::string &shadername) layer->set_rgbgen(Layer::RGBGenSecondary); } else if (firstword.compare("entitythird") == 0) { layer->set_rgbgen(Layer::RGBGenTertiary); - } else if (firstword.compare("bright") == 0) { - layer->set_bright(true); + } else if ((firstword.compare("bright") == 0) || (firstword.compare("fullbright") == 0)) { + layer->set_fullbright(true); } else if (firstword.compare("environment") == 0) { layer->set_tcgen(Layer::TCGenEnvironment); - layer->set_texmap(Layer::TexMapEnvironment); + layer->set_texmap(Layer::TexMapEnvironment); + } else if (firstword.compare("blendfunc") == 0) { + if (linestream >> firstword) { + aux::to_lowercase(firstword); + if (firstword.compare("none") == 0) { + layer->set_blendfunc(Layer::BlendFuncNone); + } else if (firstword.compare("add") == 0) { + layer->set_blendfunc(Layer::BlendFuncAdd); + } else if (firstword.compare("blend") == 0) { + layer->set_blendfunc(Layer::BlendFuncBlend); + } else { + con_warn << shaderfile.name() << " unknown blend function '" << firstword << "' at line " << linenumber << std::endl; + } + } else { + con_warn << shaderfile.name() << " missing blend function at line " << linenumber << std::endl; + } } else if (firstword.compare("map") == 0) { if (linestream >> firstword) { @@ -323,6 +357,8 @@ void Material::load_shaderfile(const std::string &shadername) } } } + } else { + con_warn << shaderfile.name() << " missing texture map at line " << linenumber << std::endl; } } else { con_warn << shaderfile.name() << " unknown layer key '" << firstword << "' at line " << linenumber << std::endl; @@ -357,7 +393,7 @@ Material *Material::find(const std::string &name) return 0; } -Material *Material::load(const std::string &name, const bool bright) +Material *Material::load(const std::string &name, const bool ui_texture) { // check if the requested material already exist Material *material = find(name); @@ -374,7 +410,10 @@ Material *Material::load(const std::string &name, const bool bright) // add a texture layer->set_texture(name); - layer->set_bright(bright); + if (ui_texture) { + layer->set_fullbright(true); + layer->set_blendfunc(Layer::BlendFuncBlend); + } if (material_imageloaderfunc) { material_imageloaderfunc(layer); if ((layer->size().width() > 0) && (layer->size().height() > 0)) { diff --git a/src/model/material.h b/src/model/material.h index 2e3a696..a3ad5fc 100644 --- a/src/model/material.h +++ b/src/model/material.h @@ -154,6 +154,9 @@ public: return material_layers; } + /** + * @brief layers in this material + * */ inline Layers & layers() { return material_layers; @@ -161,6 +164,9 @@ public: /* ---- static ----------------------------------------------------- */ + /** + * @brief material registry + * */ static inline Registry registry() { return material_registry; @@ -192,8 +198,9 @@ public: * 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. + * @param ui_texture set to true if the material is a material used by the user interface */ - static Material *load(const std::string &name, const bool bright=false); + static Material *load(const std::string &name, const bool ui_texture=false); /** * @brief find a material in the registry -- cgit v1.2.3