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

Revision 3071, 10.0 KB checked in by mattausch, 16 years ago (diff)

worked on dynamic objects

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