Skip to content

Commit

Permalink
GRAPHICS: Split material into static and dynamic ones
Browse files Browse the repository at this point in the history
  • Loading branch information
DrMcCoy committed Jan 21, 2014
1 parent 24c92d5 commit 4c8e2b7
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 11 deletions.
51 changes: 43 additions & 8 deletions src/graphics/materialman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "common/ustring.h"
#include "common/error.h"
#include "common/util.h"
#include "common/uuid.h"
#include "common/threads.h"

#include "graphics/textureman.h"
Expand All @@ -51,6 +52,8 @@ MaterialDeclaration::MaterialDeclaration() {
}

void MaterialDeclaration::reset() {
dynamic = false;

ambient [0] = 1.0; ambient [1] = 1.0; ambient [2] = 1.0;
diffuse [0] = 1.0; diffuse [1] = 1.0; diffuse [2] = 1.0; diffuse [3] = 1.0;
specular [0] = 1.0; specular [1] = 1.0; specular [2] = 1.0; specular[3] = 1.0;
Expand Down Expand Up @@ -79,9 +82,10 @@ MaterialManager::MaterialManager() {
MaterialManager::~MaterialManager() {
}

Ogre::MaterialPtr MaterialManager::get(const Common::UString &texture) {
Ogre::MaterialPtr MaterialManager::get(const Common::UString &texture, bool dynamic) {
MaterialDeclaration decl;

decl.dynamic = dynamic;
decl.textures.push_back(texture);

return get(decl);
Expand All @@ -96,27 +100,54 @@ Ogre::MaterialPtr MaterialManager::get(const MaterialDeclaration &decl) {
return RequestMan.callInMainThread(functor);
}

Common::UString name = canonicalName(decl);
Common::UString name;
if (!decl.dynamic) {
name = canonicalName(decl);

Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(name.c_str());
if (!material.isNull())
return material;
Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(name.c_str());
if (!material.isNull())
return material;

material = Ogre::MaterialManager::getSingleton().create(name.c_str(), "General");
} else
name = dynamicName();

Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create(name.c_str(), "General");

create(decl, material);

return material;
}

Ogre::MaterialPtr MaterialManager::getSolidColor(float r, float g, float b, float a) {
Ogre::MaterialPtr MaterialManager::getSolidColor(float r, float g, float b, float a, bool dynamic) {
MaterialDeclaration decl;

decl.dynamic = dynamic;
decl.diffuse[0] = r; decl.diffuse[1] = g; decl.diffuse[2] = b; decl.diffuse[3] = a;

return get(decl);
}

Ogre::MaterialPtr MaterialManager::createDynamic() {
Common::UString name = dynamicName();

return Ogre::MaterialManager::getSingleton().create(name.c_str(), "General");
}

bool MaterialManager::isDynamic(const Ogre::MaterialPtr &material) {
assert(!material.isNull());

return !Common::UString(material->getName().c_str()).beginsWith("static/");
}

Ogre::MaterialPtr MaterialManager::makeDynamic(Ogre::MaterialPtr material) {
if (isDynamic(material))
return material;

Common::UString name = dynamicName();

return material->clone(name.c_str());
}

void MaterialManager::createSolidColor(const MaterialDeclaration &decl, Ogre::MaterialPtr material) {
Ogre::TextureUnitState *texState = material->getTechnique(0)->getPass(0)->createTextureUnitState();

Expand Down Expand Up @@ -226,10 +257,14 @@ static Common::UString concat(const bool *b, uint n) {
}

Common::UString MaterialManager::canonicalName(const MaterialDeclaration &decl) {
return concat(decl.textures) +
return Common::UString("static/") + concat(decl.textures) +
concat(decl.ambient, 3) + concat(decl.diffuse, 4) + concat(decl.specular, 4) +
concat(decl.selfIllum, 3) + concat(&decl.shininess, 1) +
concat(&decl.receiveShadows, 1) + concat(&decl.writeColor, 1) + concat(&decl.writeDepth, 1);
}

Common::UString MaterialManager::dynamicName() {
return Common::UString("dynamic/") + Common::generateIDRandomString();
}

} // End of namespace Graphics
24 changes: 21 additions & 3 deletions src/graphics/materialman.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
namespace Graphics {

struct MaterialDeclaration {
bool dynamic;

float ambient[3];
float diffuse[4];
float specular[4];
Expand All @@ -62,25 +64,41 @@ struct MaterialDeclaration {
void trimTextures();
};

/** The global material manager. */
/** The global material manager.
*
* A material can be either static or dynamic. A static material won't change
* during its lifetime, and therefore only one instance of a material with
* the exact same properties will exist. A dynamic material can change; each
* dynamic material is its own unique instance.
*/
class MaterialManager : public Common::Singleton<MaterialManager> {
public:
MaterialManager();
~MaterialManager();

/** Is this a dynamic material? */
bool isDynamic(const Ogre::MaterialPtr &material);

/** Get/Load a material with a single texture. */
Ogre::MaterialPtr get(const Common::UString &texture);
Ogre::MaterialPtr get(const Common::UString &texture, bool dynamic = false);
/** Get/Load a more complex material. */
Ogre::MaterialPtr get(const MaterialDeclaration &decl);

/** Create a dynamic material. */
Ogre::MaterialPtr createDynamic();

/** Convert a static material into a dynamic material. */
Ogre::MaterialPtr makeDynamic(Ogre::MaterialPtr material);

/** Get a default material with a solid color. */
Ogre::MaterialPtr getSolidColor(float r, float g, float b, float a = 1.0);
Ogre::MaterialPtr getSolidColor(float r, float g, float b, float a = 1.0, bool dynamic = false);

private:
void create(const MaterialDeclaration &decl, Ogre::MaterialPtr material);
void createSolidColor(const MaterialDeclaration &decl, Ogre::MaterialPtr material);

Common::UString canonicalName(const MaterialDeclaration &decl);
Common::UString dynamicName();
};

} // End of namespace Graphics
Expand Down

0 comments on commit 4c8e2b7

Please sign in to comment.