-/* $Id$
-
-This file is part of libmspgl
-Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions
-Distributed under the LGPL
-*/
-
+#include <msp/gl/extensions/msp_legacy_features.h>
#include "gl.h"
#include "material.h"
+#include "resources.h"
namespace Msp {
namespace GL {
-Material::Material():
- ambient(0.2),
- diffuse(0.8),
- specular(0),
- emission(0),
- shininess(0)
-{ }
+Material::Material()
+{
+ set_ambient(0.2);
+ set_diffuse(0.8);
+ set_specular(0);
+ set_emission(0);
+ set_shininess(0);
+ set_reflectivity(0);
+}
+
+void Material::update_parameter(int mask) const
+{
+ if(cur_obj!=this)
+ return;
+
+ if(mask&AMBIENT)
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &ambient.r);
+ if(mask&DIFFUSE)
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &diffuse.r);
+ if(mask&SPECULAR)
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &specular.r);
+ if(mask&EMISSION)
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &emission.r);
+ if(mask&SHININESS)
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
+}
void Material::set_ambient(const Color &a)
{
ambient = a;
+ shdata.uniform("material.ambient", ambient);
+ update_parameter(AMBIENT);
}
void Material::set_diffuse(const Color &d)
{
diffuse = d;
+ shdata.uniform("material.diffuse", diffuse);
+ update_parameter(DIFFUSE);
}
void Material::set_specular(const Color &s)
{
specular = s;
+ shdata.uniform("material.specular", specular);
+ update_parameter(SPECULAR);
}
void Material::set_emission(const Color &e)
{
emission = e;
+ shdata.uniform("material.emission", emission);
+ update_parameter(EMISSION);
}
void Material::set_shininess(float s)
{
shininess = s;
+ shdata.uniform("material.shininess", shininess);
+ update_parameter(SHININESS);
}
-void Material::bind() const
+void Material::set_reflectivity(float r)
{
- if(current!=this)
- {
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &ambient.r);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &diffuse.r);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &specular.r);
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, &emission.r);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
- current = this;
- }
+ reflectivity = r;
+ shdata.uniform("reflectivity", reflectivity);
}
-void Material::unbind()
+void Material::bind() const
{
- current = 0;
-}
+ static Require _req(MSP_legacy_features);
-const Material *Material::current = 0;
+ if(set_current(this))
+ update_parameter(-1);
+}
Material::Loader::Loader(Material &m):
- DataFile::ObjectLoader<Material>(m)
+ DataFile::CollectionObjectLoader<Material>(m, 0)
+{
+ init();
+}
+
+Material::Loader::Loader(Material &m, Collection &c):
+ DataFile::CollectionObjectLoader<Material>(m, &c)
{
+ init();
+}
+
+void Material::Loader::init()
+{
+ if(Resources *res = dynamic_cast<Resources *>(coll))
+ srgb = res->get_srgb_conversion();
+ else
+ srgb = false;
+
add("ambient", &Loader::ambient);
add("diffuse", &Loader::diffuse);
add("specular", &Loader::specular);
add("emission", &Loader::emission);
- add("shininess", &Material::shininess);
+ add("shininess", &Loader::shininess);
+ add("reflectivity", &Loader::reflectivity);
+}
+
+Color Material::Loader::make_color(float r, float g, float b, float a)
+{
+ Color c(r, g, b, a);
+ if(srgb)
+ c = c.to_linear();
+ return c;
}
void Material::Loader::ambient(float r, float g, float b, float a)
{
- obj.ambient = GL::Color(r, g, b, a);
+ obj.set_ambient(make_color(r, g, b, a));
}
void Material::Loader::diffuse(float r, float g, float b, float a)
{
- obj.diffuse = GL::Color(r, g, b, a);
+ obj.set_diffuse(make_color(r, g, b, a));
}
void Material::Loader::specular(float r, float g, float b, float a)
{
- obj.specular = GL::Color(r, g, b, a);
+ obj.set_specular(make_color(r, g, b, a));
}
void Material::Loader::emission(float r, float g, float b, float a)
{
- obj.emission = GL::Color(r, g, b, a);
+ obj.set_emission(make_color(r, g, b, a));
+}
+
+void Material::Loader::shininess(float s)
+{
+ obj.set_shininess(s);
+}
+
+void Material::Loader::reflectivity(float r)
+{
+ obj.set_reflectivity(r);
}
} // namespace GL