1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 Also see acknowledgements in Readme.html
9 
10 You may use this sample code for anything you like, it is not covered by the
11 same license as the rest of the engine.
12 -----------------------------------------------------------------------------
13 */
14 
15 #include "MaterialGenerator.h"
16 
17 #include "OgreStringConverter.h"
18 #include "OgreException.h"
19 
20 #include "OgrePass.h"
21 #include "OgreTechnique.h"
22 
23 #include "OgreHighLevelGpuProgram.h"
24 #include "OgreHighLevelGpuProgramManager.h"
25 #include "OgreMaterialManager.h"
26 
27 #include <iostream>
28 
29 using namespace Ogre;
30 
MaterialGenerator()31 MaterialGenerator::MaterialGenerator():
32     vsMask(0), fsMask(0), matMask(0), mImpl(0)
33 {
34 }
~MaterialGenerator()35 MaterialGenerator::~MaterialGenerator()
36 {
37     // we have generated fragment shaders and materials
38     // so delete them
39     for(ProgramMap::iterator it = mFs.begin(); it != mFs.end(); ++it) {
40         HighLevelGpuProgramManager::getSingleton().remove(it->second);
41     }
42     for(MaterialMap::iterator it = mMaterials.begin(); it != mMaterials.end(); ++it) {
43         MaterialManager::getSingleton().remove(it->second);
44     }
45 
46     delete mImpl;
47 }
48 
getMaterial(Perm permutation)49 const MaterialPtr &MaterialGenerator::getMaterial(Perm permutation)
50 {
51     /// Check if material/shader permutation already was generated
52     MaterialMap::iterator i = mMaterials.find(permutation);
53     if(i != mMaterials.end())
54     {
55         return i->second;
56     }
57     else
58     {
59         /// Create it
60         MaterialPtr templ = getTemplateMaterial(permutation & matMask);
61         GpuProgramPtr vs = getVertexShader(permutation & vsMask);
62         GpuProgramPtr fs = getFragmentShader(permutation & fsMask);
63 
64         /// Create material name
65         String name = materialBaseName + StringConverter::toString(permutation);
66 
67         std::cerr << name << " " << vs->getName() << " " << fs->getName() << std::endl;
68         /// Create material from template, and set shaders
69         MaterialPtr mat = templ->clone(name);
70         Technique *tech = mat->getTechnique(0);
71         Pass *pass = tech->getPass(0);
72         pass->setFragmentProgram(fs->getName());
73         pass->setVertexProgram(vs->getName());
74 
75         /// And store it
76         mMaterials[permutation] = mat;
77         return mMaterials[permutation];
78     }
79 }
80 
getVertexShader(Perm permutation)81 const GpuProgramPtr &MaterialGenerator::getVertexShader(Perm permutation)
82 {
83     ProgramMap::iterator i = mVs.find(permutation);
84     if(i != mVs.end())
85     {
86         return i->second;
87     }
88     else
89     {
90         /// Create it
91         mVs[permutation] = mImpl->generateVertexShader(permutation);
92         return mVs[permutation];
93     }
94 }
95 
getFragmentShader(Perm permutation)96 const GpuProgramPtr &MaterialGenerator::getFragmentShader(Perm permutation)
97 {
98     ProgramMap::iterator i = mFs.find(permutation);
99     if(i != mFs.end())
100     {
101         return i->second;
102     }
103     else
104     {
105         /// Create it
106         mFs[permutation] = mImpl->generateFragmentShader(permutation);
107         return mFs[permutation];
108     }
109 }
110 
getTemplateMaterial(Perm permutation)111 const MaterialPtr &MaterialGenerator::getTemplateMaterial(Perm permutation)
112 {
113     MaterialMap::iterator i = mTemplateMat.find(permutation);
114     if(i != mTemplateMat.end())
115     {
116         return i->second;
117     }
118     else
119     {
120         /// Create it
121         mTemplateMat[permutation] = mImpl->generateTemplateMaterial(permutation);
122         return mTemplateMat[permutation];
123     }
124 }
125 
~Impl()126 MaterialGenerator::Impl::~Impl()
127 {
128 }
129 
130