Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
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
parent25a7edee2f003f259fc3a97bbfc047d72adaa361 (diff)
Initial support for multi-layered materials, requires shaders files in the new format.
-rw-r--r--src/client/savegamemenu.cc38
-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
-rw-r--r--src/render/draw.cc11
-rw-r--r--src/render/state.cc133
-rw-r--r--src/render/state.h42
-rw-r--r--src/render/textures.cc19
-rw-r--r--src/render/textures.h4
-rw-r--r--src/ui/paint.cc119
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