source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp @ 3127

Revision 3127, 10.5 KB checked in by mattausch, 16 years ago (diff)
Line 
1#include "ResourceManager.h"
2#include "Matrix4x4.h"
3#include "Geometry.h"
4#include "SceneEntity.h"
5#include "Material.h"
6#include "Texture.h"
7#include "gzstream.h"
8#include "Vector3.h"
9#include "Transform3.h"
10#include "Shape.h"
11#include "LODInfo.h"
12#include "RenderState.h"
13#include "ShaderProgram.h"
14#include "ShaderManager.h"
15
16
17#ifdef _CRT_SET
18        #define _CRTDBG_MAP_ALLOC
19        #include <stdlib.h>
20        #include <crtdbg.h>
21
22        // redefine new operator
23        #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
24        #define new DEBUG_NEW
25#endif
26
27
28using namespace std;
29
30
31namespace CHCDemoEngine
32{
33
34
35// only instance of the resource manager
36ResourceManager *ResourceManager::sResourceManager = NULL;
37
38
39ResourceManager::ResourceManager()
40{
41        mUseNormalMapping = false;
42}
43
44
45ResourceManager::~ResourceManager()
46{
47        // delete all resources.
48        CLEAR_CONTAINER(mSceneEntities);
49        CLEAR_CONTAINER(mGeometry);
50        CLEAR_CONTAINER(mMaterials);
51        CLEAR_CONTAINER(mTextures);
52        CLEAR_CONTAINER(mTrafos);
53        CLEAR_CONTAINER(mShapes);
54        //CLEAR_CONTAINER(mLODs);
55}
56
57
58void ResourceManager::DelSingleton()
59{
60        DEL_PTR(sResourceManager);
61}
62
63
64SceneEntity *ResourceManager::LoadSceneEntity(igzstream &str)
65{       
66        bool hasTrafo;
67        str.read(reinterpret_cast<char *>(&hasTrafo), sizeof(bool));
68       
69        SceneEntity *sceneGeom;
70        Transform3 *trafo;
71
72        if (!hasTrafo)
73        {
74                // identity
75                trafo = new Transform3();
76        }
77        else
78        {
79                Matrix4x4 m;
80                str.read(reinterpret_cast<char *>(m.x), sizeof(Matrix4x4));
81               
82                trafo = new Transform3(m);
83        }
84
85        mTrafos.push_back(trafo);
86
87        sceneGeom = new SceneEntity(trafo);
88
89
90        ///////////////
91        //-- load LOD levels
92
93        // note: lods must be ordered from smallest distance to largest
94        int numLODs;
95        str.read(reinterpret_cast<char *>(&numLODs), sizeof(int));
96
97        for (int i = 0; i < numLODs; ++ i)
98        {
99                // the distance until the next LOD level is used
100                float dist;
101                str.read(reinterpret_cast<char *>(&dist), sizeof(float));
102
103                int numShapes;
104                str.read(reinterpret_cast<char *>(&numShapes), sizeof(int));
105
106                //LODLevel *lodLevel = new LODLevel(dist);
107                LODLevel lodLevel(dist);
108
109                for (int j = 0; j < numShapes; ++ j)
110                {
111                        int shapeId;
112                        str.read(reinterpret_cast<char *>(&shapeId), sizeof(int));
113
114                        Geometry *geom = mGeometryTable[shapeId];
115                        Material *mat = mMaterialTable[shapeId];
116
117                        // create shape
118                        Shape *shape = new Shape(geom, mat);
119
120                        mShapes.push_back(shape);
121
122                        sceneGeom->AddShape(shape);
123                        lodLevel.AddShape(shape);
124                }
125
126                //mLODs.push_back(lodLevel);
127                sceneGeom->AddLODLevel(lodLevel);
128        }
129
130
131        static ShaderProgram *sTreeAnimationProgram =
132                ShaderManager::GetSingleton()->GetShaderProgram("treeAnimation");
133        static ShaderProgram *sTreeAnimationProgramMrt =
134                ShaderManager::GetSingleton()->GetShaderProgram("treeAnimationMrt");
135
136
137        ///////////
138        //-- hack: add tree animation (should be done per material script!)
139
140        if (numLODs > 1)
141        {
142                ShapeContainer::iterator sstart, send;
143
144                // only use shader for the first two lod levels (the non-billboards)
145                for (int i = 0; i < min(numLODs, 2); ++ i)
146                //for (int i = 0; i < numLODs; ++ i)
147                {
148                        sceneGeom->GetLODLevel(i, sstart, send);
149
150                        for (ShapeContainer::iterator it = sstart; it != send; ++ it)
151                        {
152                                Shape *shape = *it;
153
154                                Material *mat = shape->GetMaterial();
155
156                                // add the vertex animation program
157                                for (int i = 0; i < 3; ++ i)
158                                {
159                                        Technique *tech = mat->GetTechnique(i);
160
161                                        GPUProgramParameters *vtxParams = tech->GetVertexProgramParameters();
162
163                                        if (i == 0)
164                                        {
165                                                tech->SetVertexProgram(sTreeAnimationProgram);
166                                                vtxParams->SetLightDirParam(5);
167                                        }
168                                        else
169                                        {
170                                                tech->SetVertexProgram(sTreeAnimationProgramMrt);
171                                                vtxParams->SetOldTimerParam(5);
172                                        }
173
174                                        /// use a timer to simulate the moving of the tree in the wind
175                                        vtxParams->SetTimerParam(0);
176
177                                        // wind direction
178                                        static Vector3 windDir = Normalize(Vector3(0.8f, 0.2f, 0.0f));
179                                        vtxParams->SetValue3f(1, windDir.x, windDir.y, windDir.z);
180                                        // amplitude
181                                        vtxParams->SetValue1f(2, 0.3f);
182
183                                        AxisAlignedBox3 box = sceneGeom->GetBoundingBox();
184                                        vtxParams->SetValue2f(3, box.Min().z, box.Max().z);
185                                        // frequency
186                                        vtxParams->SetValue1f(4, 0.1f);
187                                }
188                        }
189                }
190        }
191
192        return sceneGeom;
193}
194
195
196void ResourceManager::LoadTextures(igzstream &str)
197{
198        int numTextures;
199        str.read(reinterpret_cast<char *>(&numTextures), sizeof(int));
200       
201        for (int i = 0; i < numTextures; ++ i)
202        {
203                // load texture name
204                int texnameSize;
205                str.read(reinterpret_cast<char *>(&texnameSize), sizeof(int));
206
207                char *texname = new char[texnameSize];
208                str.read(texname, sizeof(char) * texnameSize);
209
210                Texture *tex = new Texture(model_path + texname);
211
212                int boundS, boundT;
213
214                str.read(reinterpret_cast<char *>(&boundS), sizeof(int));
215                str.read(reinterpret_cast<char *>(&boundT), sizeof(int));
216
217                tex->SetBoundaryModeS(boundS);
218                tex->SetBoundaryModeT(boundT);
219
220                tex->Create();
221
222                mTextureTable[i] = tex;
223                mTextures.push_back(tex);
224
225                delete [] texname;
226        }
227
228        cout << "loaded " << (int)mTextureTable.size() << " textures" << endl;
229}
230
231
232void ResourceManager::LoadShapes(igzstream &str)
233{
234        int numShapes;
235        str.read(reinterpret_cast<char *>(&numShapes), sizeof(int));
236
237        for (int i = 0; i < numShapes; ++ i)
238        {
239                Geometry *geom = LoadGeometry(str);
240                Material *mat = LoadMaterial(str);
241
242                mGeometryTable[i] = geom;
243                mMaterialTable[i] = mat;               
244
245                mGeometry.push_back(geom);
246                mMaterials.push_back(mat);
247        }
248
249        cout << "loaded " << (int)mGeometryTable.size() << " shapes" << endl;
250}
251
252
253Material *ResourceManager::LoadMaterial(igzstream &str)
254{
255        // default material
256        Material *mat = new Material();
257       
258        // set default fragment + vertex programs
259        Technique *tech = mat->GetDefaultTechnique();
260
261        // texture
262        int texId;
263        str.read(reinterpret_cast<char *>(&texId), sizeof(int));
264
265        if (texId >= 0)
266                tech->SetTexture(mTextureTable[texId]);
267       
268        str.read(reinterpret_cast<char *>(&tech->mAlphaTestEnabled), sizeof(bool));
269        str.read(reinterpret_cast<char *>(&tech->mCullFaceEnabled), sizeof(bool));
270
271        // gl material
272        bool hasGlMaterial;
273        str.read(reinterpret_cast<char *>(&hasGlMaterial), sizeof(bool));
274
275        if (hasGlMaterial)
276        {
277                // only write rgb part of the material
278                str.read(reinterpret_cast<char *>(&tech->mAmbientColor), sizeof(Vector3));
279                str.read(reinterpret_cast<char *>(&tech->mDiffuseColor), sizeof(Vector3));
280                str.read(reinterpret_cast<char *>(&tech->mEmmisiveColor), sizeof(Vector3));
281                str.read(reinterpret_cast<char *>(&tech->mSpecularColor), sizeof(Vector3));
282        }
283
284
285        ///////////////
286        //-- add technique for deferred shading
287
288        static ShaderProgram *sDefaultFragmentProgramMrt = ShaderManager::GetSingleton()->GetShaderProgram("defaultFragmentMrt");
289        static ShaderProgram *sDefaultFragmentTexProgramMrt = ShaderManager::GetSingleton()->GetShaderProgram("defaultFragmentTexMrt");
290        static ShaderProgram *sDefaultVertexProgramMrt = ShaderManager::GetSingleton()->GetShaderProgram("defaultVertexMrt");
291
292        static ShaderProgram *sNormalMappingVertexProgramMrt = ShaderManager::GetSingleton()->GetShaderProgram("normalMappingVertexMrt");
293        static ShaderProgram *sNormalMappingFragmentProgramMrt = ShaderManager::GetSingleton()->GetShaderProgram("normalMappingFragmentMrt");
294
295        Technique *deferred = new Technique(*tech);
296
297        if (deferred->GetTexture())
298                deferred->SetFragmentProgram(sDefaultFragmentTexProgramMrt);
299        else
300                deferred->SetFragmentProgram(sDefaultFragmentProgramMrt);
301
302        deferred->GetFragmentProgramParameters()->SetViewMatrixParam(0);
303
304        deferred->SetVertexProgram(sDefaultVertexProgramMrt);
305
306        deferred->GetVertexProgramParameters()->SetModelMatrixParam(1);
307        deferred->GetVertexProgramParameters()->SetOldModelMatrixParam(2);
308
309        mat->AddTechnique(deferred);
310       
311
312        ///////////
313        //-- add depth pass
314
315        Technique *depthPass = new Technique(*tech);
316
317        depthPass->SetColorWriteEnabled(false);
318        depthPass->SetLightingEnabled(false);
319        mat->AddTechnique(depthPass);
320
321        return mat;
322}
323
324
325Geometry *ResourceManager::LoadGeometry(igzstream &str)
326{
327        Vector3 *vertices;
328        Vector3 *normals;
329        Texcoord2 *texcoords;
330
331
332        //////////////
333        //-- read in vertices
334
335        int vertexCount;
336        str.read(reinterpret_cast<char *>(&vertexCount), sizeof(int));
337       
338        // end of file reached
339        if (str.eof()) return NULL;
340
341        //cout << "vertexcount: " << vertexCount << endl;
342
343        vertices = new Vector3[vertexCount];
344    str.read(reinterpret_cast<char *>(vertices), sizeof(Vector3) * vertexCount);
345       
346        normals = new Vector3[vertexCount];
347        str.read(reinterpret_cast<char *>(normals), sizeof(Vector3) * vertexCount);
348
349        Vector3 *tangents;
350
351        if (mUseNormalMapping)
352        {
353                tangents = new Vector3[vertexCount];
354                str.read(reinterpret_cast<char *>(tangents), sizeof(Vector3) * vertexCount);
355        }
356        else
357        {
358                tangents = NULL;
359        }
360
361        int texCoordCount;
362        str.read(reinterpret_cast<char *>(&texCoordCount), sizeof(int));
363
364        if (texCoordCount)
365        {
366                texcoords = new Texcoord2[texCoordCount];
367                str.read(reinterpret_cast<char *>(texcoords), sizeof(Texcoord2) * texCoordCount);
368        }
369        else
370        {
371                texcoords = NULL;
372        }
373
374        const bool delGeometry = false;
375        return new Geometry(vertices, normals, texcoords, vertexCount, delGeometry, tangents);
376}
377
378
379void ResourceManager::LoadSceneEntities(igzstream &str,
380                                                                                SceneEntityContainer &entities)
381{
382        int entityCount;
383        str.read(reinterpret_cast<char *>(&entityCount), sizeof(int));
384
385        entities.reserve(entityCount);
386
387        for (int i = 0; i < entityCount; ++ i)
388        {
389                SceneEntity *ent = LoadSceneEntity(str);
390
391                // return loaded entities
392                entities.push_back(ent);
393                // also store internally
394                mSceneEntities.push_back(ent);
395        }
396
397        cout << "loaded " << entityCount << " scene entities" << endl;
398}
399
400
401bool ResourceManager::Load(const std::string &filename,
402                                                   SceneEntityContainer &entities)
403{
404        igzstream istr(filename.c_str());
405       
406        if (!istr.is_open())
407                return false;
408
409        cout << "loading textures" << endl;
410       
411        // load the texture table
412        LoadTextures(istr);
413
414        cout << "loading shapes (geometry + materials)" << endl;
415
416        // load the shapees
417        LoadShapes(istr);
418
419        cout << "loading scene entites" << endl;
420        LoadSceneEntities(istr, entities);
421       
422        cout << "bin loading finished" << endl;
423
424        // clean up
425        mTextureTable.clear();
426        mGeometryTable.clear();
427        mMaterialTable.clear();
428
429        return true;
430}
431
432
433void ResourceManager::AddSceneEntity(SceneEntity *ent)
434{
435        mSceneEntities.push_back(ent);
436}
437
438
439Transform3 *ResourceManager::CreateTransform(const Matrix4x4 &m)
440{
441        Transform3 *t = new Transform3(m);
442
443        mTrafos.push_back(t);
444        return t;
445}
446
447}
Note: See TracBrowser for help on using the repository browser.