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

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