NLS Engine  v0.1
The Next Logical Step in game engine design.
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines
MaterialsSystemInterface.cpp
Go to the documentation of this file.
00001 
00011 #include "MaterialsSystemInterface.h"
00012 
00013 // Standard Includes
00014 #include <cassert>
00015 #include <set>
00016 
00017 // Library Includes
00018 #include <boost/lexical_cast.hpp>
00019 
00020 // Local Includes
00021 #include "../../sharedbase/Envelope.h"
00022 #include "../Materials.h"
00023 
00024 #include "MaterialInterface.h"
00025 #include "BasicMaterial.h"
00026 
00027 // Forward Declarations
00028 
00029 // Typedefs
00030 namespace GraphicsCore {
00031   typedef std::set<MaterialInterface*> MatSet;
00032 }
00033 
00034 // Local Constants
00035 
00036 // Class Methods
00037 namespace GraphicsCore {
00038   static MatSet gMaterials;
00039 
00040   /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00041   MaterialInterface* MaterialsSystemInterface::CreateMaterial(EnvelopeSPTR envelope) {
00042     MaterialInterface* material = nullptr;
00043     
00044     switch (envelope->msgid) {
00045       case ID_MATERIAL_BASIC: {
00046         Color ambient, diffuse, specular, emissive;
00047         float power = 0.0f;
00048         
00049         ambient = diffuse = specular = Color(1.0f, 1.0f, 1.0f, 1.0f);
00050         emissive = Color(0.0f, 0.0f, 0.0f, 1.0f);
00051         
00052         {
00053           unsigned int colorType;
00054           float red, green, blue, alpha;
00055           
00056           bool safe = true;
00057           
00058           unsigned int count = envelope->GetCount();
00059           for (unsigned int index = 0; index < count && safe; ++index) {
00060             colorType = envelope->GetDataUInt(index);
00061             switch (colorType) {
00062               case ID_MATERIAL_COLOR_AMBIENT:
00063               case ID_MATERIAL_COLOR_DIFFUSE:
00064               case ID_MATERIAL_COLOR_SPECULAR:
00065               case ID_MATERIAL_COLOR_EMISSIVE: {
00066                 // Get the values
00067                 red   = envelope->GetDataFloat(index + 1);
00068                 green = envelope->GetDataFloat(index + 2);
00069                 blue  = envelope->GetDataFloat(index + 3);
00070                 alpha = envelope->GetDataFloat(index + 4);
00071                 
00072                 // Consume the positions used.
00073                 index += 4;
00074                 
00075                 // Go do the unique processing.
00076                 switch (colorType) {
00077                   case ID_MATERIAL_COLOR_AMBIENT: {
00078                     ambient = Color(red, green, blue, alpha);
00079                   }
00080                   break;
00081                   case ID_MATERIAL_COLOR_DIFFUSE: {
00082                     diffuse = Color(red, green, blue, alpha);
00083                   }
00084                   break;
00085                   case ID_MATERIAL_COLOR_SPECULAR: {
00086                     specular = Color(red, green, blue, alpha);
00087                   }
00088                   break;
00089                   case ID_MATERIAL_COLOR_EMISSIVE: {
00090                     emissive = Color(red, green, blue, alpha);
00091                   }
00092                   break;
00093                   // No default case needed as that has already been taken care of in the parent switch.
00094                 }
00095               }
00096               break;
00097               case ID_MATERIAL_COLOR_POWER: {
00098                 // Get the values
00099                 power = envelope->GetDataFloat(index + 1);
00100                 
00101                 // Consume the positions used.
00102                 index += 1;
00103               }
00104               break;
00105               default: {
00106                 LOG(LOG_PRIORITY::INFO, "Unknown material color type sent: " + boost::lexical_cast < std::string > (colorType));
00107                 safe = false; // Stop processing the loop: to proceed would be just garbage due to unknown types.
00108               }
00109             }
00110           }
00111         }
00112         
00113         material = new BasicMaterial(diffuse, ambient, specular, emissive, power);
00114       }
00115       break;
00116       case ID_MATERIAL_BASIC_USING_MAT: {
00117         try {
00118           material = new BasicMaterial(boost::any_cast<Material>(envelope->GetData(0)));
00119         }
00120         catch (const boost::bad_any_cast &) {
00121           LOG(LOG_PRIORITY::INFO, "Bad data type passed for new BasicMaterial using a source Material.");
00122         }
00123       }
00124       break;
00125       default: {
00126         LOG(LOG_PRIORITY::INFO, "Unknown material type: " + boost::lexical_cast < std::string > (envelope->msgid));
00127       }
00128     }
00129     
00130     // Make sure that no nulls ever get put in the materials list.
00131     if (material != nullptr) {
00132       gMaterials.insert(material);
00133     }
00134     
00135     return material;
00136   }
00137   
00138   /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00139   void MaterialsSystemInterface::DestroyMaterial(MaterialInterface* material) {
00140     // Only delete if it had been created and has not already been deleted.
00141     MatSet::iterator matit = gMaterials.find(material);
00142     if (matit != gMaterials.end()) {
00143       assert(material != nullptr); // Just be very sure.  It should be absolutely impossible to have a nullptr stored in the materials list.
00144       
00145       delete material;
00146       
00147       gMaterials.erase(matit);
00148     }
00149   }
00150   
00151 }