Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ColladaPlugin/src/OgreColladaMaterial.cpp @ 23

Last change on this file since 23 was 21, checked in by nicolasc, 17 years ago

added ogreode and Colladaplugin

File size: 9.6 KB
Line 
1/**
2 * This source file is part of OgreColladaPlugin
3 * an addon for OGRE (Object-oriented Graphics Rendering Engine)
4 * For the latest info, see http://www.ogre3d.org/
5 *
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by the Free Software
8 * Foundation; either version 2 of the License, or (at your option) any later
9 * version.
10
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14
15 * You should have received a copy of the GNU Lesser General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place - Suite 330, Boston, MA 02111-1307, USA, or go to
18 * http://www.gnu.org/copyleft/lesser.txt.
19 *
20 * @author      Philipp Hartl
21 * @see         README
22 */
23
24#include "OgreColladaMaterial.h"
25#include "OgreColladaDocument.h"
26#include "OgreColladaLibrary.h"
27#include "OgreColladaTexture.h"
28#include "OgreColladaSyntax.h"
29#include "OgreColladaUtils.h"
30
31#include "OgreMaterialManager.h"
32#include "OgreTechnique.h"
33#include "OgreStringConverter.h"
34
35namespace Ogre
36{
37        //-------------------------------------------------------------------------
38        ColladaMaterial::ColladaMaterial(ColladaDocument *doc, xmlNode *n) : ColladaEntity(doc, n) { }
39
40        //-------------------------------------------------------------------------
41        ColladaMaterial::~ColladaMaterial(void) 
42        {
43                if (!mPasses.empty())
44                {
45                        for (ColladaMaterialPassPtrVector::iterator it = mPasses.begin(); it != mPasses.end(); ++it)
46                        {
47                                if (!(*it)->mTextures.empty()) (*it)->mTextures.clear();        // the instances will be deleted by the library container!
48                                OGRE_DELETE(*it);
49                        }
50                        mPasses.clear();
51                }
52        }
53       
54        //-------------------------------------------------------------------------
55        MovableObject *ColladaMaterial::getOgreInstance(void) const
56        {
57                ushort ipass = 0;
58
59                // get new material pointer
60                MaterialPtr material = MaterialManager::getSingleton().create(mId, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
61
62                // for all passes
63                for (ColladaMaterialPassPtrVector::const_iterator it = mPasses.begin(); it != mPasses.end(); ++it)
64                {
65                        // set all parameters, ogre should take only those into account which are necessary for this shading mode
66                        material->getTechnique(0)->getPass(ipass)->setShadingMode((*it)->mMode);
67                        material->getTechnique(0)->getPass(ipass)->setAmbient((*it)->mAmbient);
68                        material->getTechnique(0)->getPass(ipass)->setDiffuse((*it)->mDiffuse);
69                        material->getTechnique(0)->getPass(ipass)->setSpecular((*it)->mSpecular);
70                        material->getTechnique(0)->getPass(ipass)->setShininess((*it)->mShininess);
71                        material->getTechnique(0)->getPass(ipass)->setSelfIllumination((*it)->mEmission);
72
73                        // for multitexturing colouroperations(_ex) must be set! (alpha_blend, src, dest)
74                        for (ColladaTexturePtrVector::iterator jt = (*it)->mTextures.begin(); jt != (*it)->mTextures.end(); ++jt)
75                        {                               
76                                material->getTechnique(0)->getPass(ipass)->createTextureUnitState((*jt)->getImage()->getSource());
77                        }
78                        ipass++;
79                }
80
81                // load material, resource loader?
82                material->load();
83
84                // TEST
85                // LogManager::getSingleton().logMessage("ColladaMaterial::createOgreMaterial - finished!");
86
87                return NULL;
88        }
89
90        //-------------------------------------------------------------------------
91        bool ColladaMaterial::doImport(void)
92        {
93                if (mLoaded) return mStatus;
94                else mLoaded = true;
95       
96                // do we need them?
97                // <asset> child
98                // xmlNode *asset = ColladaUtils::getChildByTagName(mNode, CS_ELM_ASSET);
99
100                // <param> childs
101                // xmlNodePtrVector params = ColladaUtils::getChildsByTagName(mNode, CS_ELM_PARAM);
102
103                // <shader> child
104                xmlNode *shader = ColladaUtils::getChildByTagName(mNode, CS_ELM_SHADER);
105
106                // get all <technique> childs of shader
107                xmlNodePtrVector techniques = ColladaUtils::getChildsByTagName(shader, CS_ELM_TECHNIQUE);               
108                // currently we are only interested in "COMMON" profile
109                xmlNode *technique = NULL;
110                xmlNodePtrVector::iterator it;
111                for (it = techniques.begin(); it != techniques.end(); ++it)
112                {
113                        String profile = ColladaUtils::getProperty(*it, CS_ATR_PROFILE);
114                        if (profile == CS_VAL_TECHNIQUE_PROFILE_COMMON)
115                        {
116                                technique = *it;
117                                break;
118                        }
119                }
120                if (technique == NULL) return false;
121
122                // the first <program> will be ignored
123                // get <pass> elements
124                xmlNodePtrVector passes = ColladaUtils::getChildsByTagName(technique, CS_ELM_PASS);
125                // each pass will be stored on the vector list
126                for (it = passes.begin(); it != passes.end(); ++it) mPasses.push_back(importPass(*it));
127                if (mPasses.empty()) return false;
128
129                // TEST
130                getOgreInstance();
131
132                mStatus = true;
133                return mStatus;
134        }
135
136        //-------------------------------------------------------------------------
137        ColladaMaterialPass *ColladaMaterial::importPass(xmlNode *pass)
138        {
139                ColladaMaterialPass *newpass = new ColladaMaterialPass;
140
141                // do we need the <param> node(s)?
142
143                /**
144                 * import <input> tags, maybe there are textures
145                 * get source out of input texture node and try to
146                 * load the texture entity, push it on the texture list for multitexture purpose
147                 */ 
148                xmlNodePtrVector inputs = ColladaUtils::getChildsByTagName(pass, CS_ELM_INPUT);
149                xmlNodePtrVector::iterator it;
150                for (it = inputs.begin(); it != inputs.end(); ++it)
151                {
152                        // look for the input with semantic="TEXTURE"
153                        String semantic = ColladaUtils::getProperty(*it, CS_ATR_INPUT_SEMANTIC);
154                        if (semantic == CS_VAL_INPUT_SEMANTIC_TEXTURE) 
155                        {
156                                // get source attribute
157                                String source = ColladaUtils::getProperty(*it, CS_ATR_INPUT_SOURCE);
158                                if (source.empty())
159                                {
160                                        LogManager::getSingleton().logMessage("ColladaMaterial::importPass - no source url for texture is given! " + mId);
161                                        continue;
162                                }
163
164                                // local reference of texture file
165                                if (source.find("#") == 0)
166                                {
167                                        source.erase(0,1);
168
169                                        // try to find the instance and load it, if it is not already loaded
170                                        ColladaTexture *texture = mDoc->getLibrary()->getTexture(source);
171                                        if (texture == NULL)
172                                        {
173                                                LogManager::getSingleton().logMessage("ColladaMaterial::importPass - can't find the texture reference " + source + "! " + mId);
174                                                continue;
175                                        }
176                                        // try to import the entity
177                                        if (!texture->doImport())
178                                        {
179                                                LogManager::getSingleton().logMessage("ColladaMaterial::importPass - loading of texture " + source + " failed! " + mId);
180                                                continue;
181                                        }
182
183                                        // save valid texture on the list
184                                        newpass->mTextures.push_back(texture);
185                                }
186                                // external
187                                else
188                                {
189                                        LogManager::getSingleton().logMessage("ColladaMaterial::importPass - external refernces are currently not implemented! " + mId);
190                                        continue;
191                                }
192                        }
193                }
194
195                // get <program>
196                xmlNode *program = ColladaUtils::getChildByTagName(pass, CS_ELM_PROGRAM);
197               
198                // possible material shader types: CONSTANT, LAMBERT, PHONG
199                String programUrl = ColladaUtils::getProperty(program, CS_ATR_URL);
200                newpass->mMode = SO_GOURAUD;    // lambert
201                if (programUrl == CS_VAL_PROGRAM_URL_PHONG) newpass->mMode = SO_PHONG;
202                else if (programUrl == CS_VAL_PROGRAM_URL_CONSTANT) newpass->mMode = SO_FLAT;
203       
204                // reset all colours
205                newpass->mAmbient = ColourValue(0,0,0,0);
206                newpass->mDiffuse = ColourValue(0,0,0,0);
207                newpass->mSpecular = ColourValue(0,0,0,0);
208                newpass->mShininess = 0.0;
209                newpass->mEmission = ColourValue(0,0,0,0);
210                newpass->mReflective = ColourValue(0,0,0,0);
211                newpass->mReflectivity = 0.0; // mattle
212                newpass->mTransparent = ColourValue(0,0,0,0);
213                newpass->mTransparency = 0.0; // opaque
214
215                // now get the <param> of the program
216                xmlNodePtrVector params = ColladaUtils::getChildsByTagName(program, CS_ELM_PARAM);
217                for (it = params.begin(); it != params.end(); ++it)
218                {
219                        // property name
220                        String name = ColladaUtils::getProperty(*it, CS_ATR_NAME);
221                        // the value
222                        String content = ColladaUtils::getContentDirect(*it);
223
224                        // TEST
225                        // LogManager::getSingleton().logMessage("ColladaMaterial::importPass - colour " + name + ": " + content);
226
227                        // AMBIENT, float3
228                        if (name == CS_VAL_MATERIAL_PARAM_AMBIENT)
229                        {
230                                newpass->mAmbient = StringConverter::parseColourValue(content);
231                        }
232                        // DIFFUSE
233                        else if (name == CS_VAL_MATERIAL_PARAM_DIFFUSE)
234                        {
235                                newpass->mDiffuse = StringConverter::parseColourValue(content);
236                        }
237                        // SPECULAR
238                        else if (name == CS_VAL_MATERIAL_PARAM_SPECULAR)
239                        {
240                                newpass->mSpecular = StringConverter::parseColourValue(content);
241                        }
242                        // SHININESS
243                        else if (name == CS_VAL_MATERIAL_PARAM_SHININESS)
244                        {
245                                newpass->mShininess = StringConverter::parseReal(content);
246                        }
247                        // TRANSPARENT
248                        else if (name == CS_VAL_MATERIAL_PARAM_TRANSPARENT)
249                        {
250                                newpass->mTransparent = StringConverter::parseColourValue(content);
251                        }
252                        // TRANSPARENCY
253                        else if (name == CS_VAL_MATERIAL_PARAM_TRANSPARENCY)
254                        {
255                                newpass->mTransparency = StringConverter::parseReal(content);
256                        }
257                        // EMISSION
258                        else if (name == CS_VAL_MATERIAL_PARAM_EMISSION)
259                        {       
260                                newpass->mEmission = StringConverter::parseColourValue(content);
261                        }
262                        // REFLECTIVE
263                        else if (name == CS_VAL_MATERIAL_PARAM_REFLECTIVE)
264                        {
265                                newpass->mReflective = StringConverter::parseColourValue(content);
266                        }
267                        // REFLECTIVITY
268                        else if (name == CS_VAL_MATERIAL_PARAM_REFLECTIVITY)
269                        {
270                                newpass->mReflectivity = StringConverter::parseReal(content);
271                        }
272                        else
273                        {
274                                LogManager::getSingleton().logMessage("ColladaMaterial::importPass - unknown attribute of material param " + name + "! " + mId);
275                        }
276                }
277
278                // set alpha value for the colours
279                float alpha = 1.0 - newpass->mTransparency;
280                newpass->mDiffuse.a = alpha;
281                newpass->mSpecular.a = alpha;
282
283                return newpass;
284        }
285}
Note: See TracBrowser for help on using the repository browser.