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

Revision 3052, 13.1 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 "Matrix4x4.h"
9#include "Vector3.h"
10#include "Transform3.h"
11#include "Shape.h"
12#include "LODInfo.h"
13#include "RenderState.h"
14#include "ShaderProgram.h"
15#include <Cg/cg.h>
16#include <Cg/cgGL.h>
17
18
19#ifdef _CRT_SET
20        #define _CRTDBG_MAP_ALLOC
21        #include <stdlib.h>
22        #include <crtdbg.h>
23
24        // redefine new operator
25        #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
26        #define new DEBUG_NEW
27#endif
28
29
30using namespace std;
31
32
33namespace CHCDemoEngine
34{
35
36
37/////////
38//-- cg stuff
39
40static CGcontext sCgContext = NULL;
41
42static CGprofile sCgFragmentProfile;
43static CGprofile sCgVertexProfile;
44
45static ShaderProgram *sTreeAnimationProgramMrt;
46static ShaderProgram *sTreeAnimationProgram;
47
48
49// only instance of the resource manager
50ResourceManager *ResourceManager::sResourceManager = NULL;
51
52
53static void cgErrorCallback()
54{
55        CGerror lastError = cgGetError();
56
57        if(lastError)
58        {
59                printf("%s\n\n", cgGetErrorString(lastError));
60                printf("%s\n", cgGetLastListing(sCgContext));
61               
62                printf("Cg error, exiting...\n");
63
64                exit(0);
65        }
66}
67
68
69ResourceManager::ResourceManager()
70{
71        InitCg();
72}
73
74
75ResourceManager::~ResourceManager()
76{
77        // delete all resources.
78        CLEAR_CONTAINER(mSceneEntities);
79        CLEAR_CONTAINER(mGeometry);
80        CLEAR_CONTAINER(mMaterials);
81        CLEAR_CONTAINER(mTextures);
82        CLEAR_CONTAINER(mTrafos);
83        CLEAR_CONTAINER(mShapes);
84        CLEAR_CONTAINER(mLODs);
85        CLEAR_CONTAINER(mGPUParameters);
86        CLEAR_CONTAINER(mShaders);
87       
88        if (sCgContext)
89                cgDestroyContext(sCgContext);
90}
91
92
93void ResourceManager::DelSingleton()
94{
95        DEL_PTR(sResourceManager);
96}
97
98
99SceneEntity *ResourceManager::LoadSceneEntity(igzstream &str)
100{       
101        bool hasTrafo;
102        str.read(reinterpret_cast<char *>(&hasTrafo), sizeof(bool));
103       
104        SceneEntity *sceneGeom;
105        Transform3 *trafo;
106
107        if (!hasTrafo)
108        {
109                // identity
110                trafo = new Transform3();
111        }
112        else
113        {
114                Matrix4x4 m;
115                str.read(reinterpret_cast<char *>(m.x), sizeof(Matrix4x4));
116               
117                trafo = new Transform3(m);
118        }
119
120        mTrafos.push_back(trafo);
121
122        sceneGeom = new SceneEntity(trafo);
123
124
125        ///////////////
126        //-- load LOD levels
127
128        // note: lods must be ordered from smallest distance to largest
129        int numLODs;
130        str.read(reinterpret_cast<char *>(&numLODs), sizeof(int));
131
132        for (int i = 0; i < numLODs; ++ i)
133        {
134                // the distance until the next LOD level is used
135                float dist;
136                str.read(reinterpret_cast<char *>(&dist), sizeof(float));
137
138                int numShapes;
139                str.read(reinterpret_cast<char *>(&numShapes), sizeof(int));
140
141                LODLevel *lodLevel = new LODLevel(dist);
142
143                for (int j = 0; j < numShapes; ++ j)
144                {
145                        int shapeId;
146                        str.read(reinterpret_cast<char *>(&shapeId), sizeof(int));
147
148                        Geometry *geom = mGeometryTable[shapeId];
149                        Material *mat = mMaterialTable[shapeId];
150
151                        // create shape
152                        Shape *shape = new Shape(geom, mat, sceneGeom);
153
154                        mShapes.push_back(shape);
155
156                        sceneGeom->AddShape(shape);
157                        lodLevel->AddShape(shape);
158                }
159
160                mLODs.push_back(lodLevel);
161                sceneGeom->AddLODLevel(lodLevel);
162        }
163
164        ///////////
165        //-- hack: add tree animation (should be done per material script!)
166
167        if (numLODs > 1)
168        {
169                ShapeContainer::iterator sstart, send;
170
171                // only use shader for the first two lod levels (the non-billboards)
172                for (int i = 0; i < min(numLODs, 2); ++ i)
173                //for (int i = 0; i < numLODs; ++ i)
174                {
175                        sceneGeom->GetLODLevel(i, sstart, send);
176
177                        for (ShapeContainer::iterator it = sstart; it != send; ++ it)
178                        {
179                                Shape *shape = *it;
180
181                                Material *mat = shape->GetMaterial();
182
183                                // add the vertex animation program
184                                for (int i = 0; i < 3; ++ i)
185                                {
186                                        Technique *tech = mat->GetTechnique(i);
187
188                                        GPUProgramParameters *vtxParams = tech->GetVertexProgramParameters();
189
190                                        if (i == 0)
191                                        {
192                                                tech->SetVertexProgram(sTreeAnimationProgram);
193                                                vtxParams->SetLightDirParam(5);
194                                        }
195                                        else
196                                        {
197                                                tech->SetVertexProgram(sTreeAnimationProgramMrt);
198                                        }
199
200                                        /// use a timer to simulate the moving of the tree in the wind
201                                        vtxParams->SetTimerParam(0);
202                                        // wind direction
203                                        static Vector3 windDir = Normalize(Vector3(0.8f, 0.2f, 0.0f));
204                                        vtxParams->SetValue3f(1, windDir.x, windDir.y, windDir.z);
205                                        // amplitude
206                                        vtxParams->SetValue1f(2, 0.3f);
207
208                                        AxisAlignedBox3 box = sceneGeom->GetBoundingBox();
209                                        vtxParams->SetValue2f(3, box.Min().z, box.Max().z);
210                                        // frequency
211                                        vtxParams->SetValue1f(4, 0.1f);
212                                }
213                        }
214                }
215        }
216
217        return sceneGeom;
218}
219
220
221void ResourceManager::LoadTextures(igzstream &str)
222{
223        int numTextures;
224        str.read(reinterpret_cast<char *>(&numTextures), sizeof(int));
225       
226        for (int i = 0; i < numTextures; ++ i)
227        {
228                // load texture name
229                int texnameSize;
230                str.read(reinterpret_cast<char *>(&texnameSize), sizeof(int));
231
232                char *texname = new char[texnameSize];
233                str.read(texname, sizeof(char) * texnameSize);
234
235                Texture *tex = new Texture(model_path + texname);
236
237                int boundS, boundT;
238
239                str.read(reinterpret_cast<char *>(&boundS), sizeof(int));
240                str.read(reinterpret_cast<char *>(&boundT), sizeof(int));
241
242                tex->SetBoundaryModeS(boundS);
243                tex->SetBoundaryModeT(boundT);
244
245                tex->Create();
246
247                mTextureTable[i] = tex;
248                mTextures.push_back(tex);
249
250                delete [] texname;
251        }
252
253        cout << "loaded " << (int)mTextureTable.size() << " textures" << endl;
254}
255
256
257void ResourceManager::LoadShapes(igzstream &str)
258{
259        int numShapes;
260        str.read(reinterpret_cast<char *>(&numShapes), sizeof(int));
261
262        for (int i = 0; i < numShapes; ++ i)
263        {
264                Geometry *geom = LoadGeometry(str);
265                Material *mat = LoadMaterial(str);
266
267                mGeometryTable[i] = geom;
268                mMaterialTable[i] = mat;               
269
270                mGeometry.push_back(geom);
271                mMaterials.push_back(mat);
272        }
273
274        cout << "loaded " << (int)mGeometryTable.size() << " shapes" << endl;
275}
276
277
278Material *ResourceManager::LoadMaterial(igzstream &str)
279{
280        // default material
281        Material *mat = new Material();
282       
283        // set default fragment + vertex programs
284        Technique *tech = mat->GetDefaultTechnique();
285
286        // texture
287        int texId;
288        str.read(reinterpret_cast<char *>(&texId), sizeof(int));
289
290        if (texId >= 0)
291                tech->SetTexture(mTextureTable[texId]);
292       
293        str.read(reinterpret_cast<char *>(&tech->mAlphaTestEnabled), sizeof(bool));
294        str.read(reinterpret_cast<char *>(&tech->mCullFaceEnabled), sizeof(bool));
295
296        // gl material
297        bool hasGlMaterial;
298        str.read(reinterpret_cast<char *>(&hasGlMaterial), sizeof(bool));
299
300        if (hasGlMaterial)
301        {
302                // only write rgb part of the material
303                str.read(reinterpret_cast<char *>(&tech->mAmbientColor), sizeof(Vector3));
304                str.read(reinterpret_cast<char *>(&tech->mDiffuseColor), sizeof(Vector3));
305                str.read(reinterpret_cast<char *>(&tech->mEmmisiveColor), sizeof(Vector3));
306                str.read(reinterpret_cast<char *>(&tech->mSpecularColor), sizeof(Vector3));
307        }
308
309
310        ///////////////
311        //-- add technique for deferred shading
312
313        Technique *deferred = new Technique(*tech);
314
315        if (deferred->GetTexture())
316        {
317                deferred->SetFragmentProgram(mMrtDefaultFragmentTexProgram);
318                deferred->GetFragmentProgramParameters()->SetViewMatrixParam(0);
319                deferred->GetFragmentProgramParameters()->SetTexture(1, tech->GetTexture()->GetId());
320        }       
321        else
322        {
323                deferred->SetFragmentProgram(mMrtDefaultFragmentProgram);
324                deferred->GetFragmentProgramParameters()->SetViewMatrixParam(0);
325        }
326
327        deferred->SetVertexProgram(mMrtDefaultVertexProgram);
328        mat->AddTechnique(deferred);
329       
330
331        ///////////
332        //-- add depth pass
333
334        Technique *depthPass = new Technique(*tech);
335        depthPass->SetColorWriteEnabled(false);
336        depthPass->SetLightingEnabled(false);
337        mat->AddTechnique(depthPass);
338
339        return mat;
340}
341
342
343Geometry *ResourceManager::LoadGeometry(igzstream &str)
344{
345        Vector3 *vertices;
346        Vector3 *normals;
347        Texcoord2 *texcoords;
348
349
350        //////////////
351        //-- read in vertices
352
353        int vertexCount;
354        str.read(reinterpret_cast<char *>(&vertexCount), sizeof(int));
355       
356        // end of file reached
357        if (str.eof()) return NULL;
358
359        //cout << "vertexcount: " << vertexCount << endl;
360
361        vertices = new Vector3[vertexCount];
362    str.read(reinterpret_cast<char *>(vertices), sizeof(Vector3) * vertexCount);
363       
364        normals = new Vector3[vertexCount];
365        str.read(reinterpret_cast<char *>(normals), sizeof(Vector3) * vertexCount);
366
367        int texCoordCount;
368        str.read(reinterpret_cast<char *>(&texCoordCount), sizeof(int));
369
370        if (texCoordCount)
371        {
372                texcoords = new Texcoord2[texCoordCount];
373                str.read(reinterpret_cast<char *>(texcoords), sizeof(Texcoord2) * texCoordCount);
374        }
375        else
376        {
377                texcoords = NULL;
378        }
379
380        return new Geometry(vertices, normals, texcoords, vertexCount, true);
381        //return new Geometry(vertices, normals, texcoords, vertexCount, false);
382}
383
384
385void ResourceManager::LoadSceneEntities(igzstream &str,
386                                                                                SceneEntityContainer &entities)
387{
388        int entityCount;
389        str.read(reinterpret_cast<char *>(&entityCount), sizeof(int));
390
391        entities.reserve(entityCount);
392
393        for (int i = 0; i < entityCount; ++ i)
394        {
395                SceneEntity *ent = LoadSceneEntity(str);
396
397                // return loaded entities
398                entities.push_back(ent);
399                // also store internally
400                mSceneEntities.push_back(ent);
401        }
402
403        cout << "loaded " << entityCount << " scene entities" << endl;
404}
405
406
407bool ResourceManager::Load(const std::string &filename,
408                                                   SceneEntityContainer &entities)
409{
410        igzstream istr(filename.c_str());
411       
412        if (!istr.is_open())
413                return false;
414
415        cout << "loading textures" << endl;
416       
417        // load the texture table
418        LoadTextures(istr);
419
420        cout << "loading shapes (geometry + materials)" << endl;
421
422        // load the shapees
423        LoadShapes(istr);
424
425        cout << "loading scene entites" << endl;
426        LoadSceneEntities(istr, entities);
427       
428        cout << "bin loading finished" << endl;
429
430        // clean up
431        mTextureTable.clear();
432        mGeometryTable.clear();
433        mMaterialTable.clear();
434
435        return true;
436}
437
438
439ShaderProgram *ResourceManager::CreateFragmentProgram(const std::string &filename,
440                                                                                                          const std::string &funcName)
441{
442        const string fullName = "src/shaders/" + filename + ".cg";
443
444        ShaderProgram *p = new ShaderProgram(sCgContext, fullName, sCgFragmentProfile, funcName);
445        mShaders.push_back(p);
446
447        if (!p->IsValid())
448        {
449                DEL_PTR(p);
450                cerr << "Program " << funcName << " in " << fullName << " failed to load" << endl;
451        }
452       
453        cout << "Program " << funcName << " in " << fullName << " loaded" << endl;
454
455        return p;
456}
457
458
459ShaderProgram *ResourceManager::CreateVertexProgram(const std::string &filename, const std::string &funcName)
460{
461        const string fullName = "src/shaders/" + filename + ".cg";
462       
463        ShaderProgram *p = new ShaderProgram(sCgContext, fullName, sCgVertexProfile, funcName);
464        mShaders.push_back(p);
465
466        if (!p->IsValid())
467        {
468                DEL_PTR(p);
469                cerr << "Program " << funcName << " in " << fullName << " failed to load" << endl;
470        }
471        else
472                cout << "Program " << funcName << " in " << fullName << " loaded" << endl;
473
474        return p;
475}
476
477
478void ResourceManager::InitCg()
479{
480        // setup cg
481        cgSetErrorCallback(cgErrorCallback);
482        // create context.
483        sCgContext = cgCreateContext();
484        // get the optimal fragment profile
485        sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
486        cgGLSetOptimalOptions(sCgFragmentProfile);
487        // get the optimal vertex profile
488        sCgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
489        cgGLSetOptimalOptions(sCgVertexProfile);
490
491        // set textures to auto load
492        cgGLSetManageTextureParameters(sCgContext, false);
493
494        mMrtDefaultVertexProgram = CreateVertexProgram("mrt", "vtx");
495        mMrtDefaultFragmentProgram = CreateFragmentProgram("mrt", "frag");
496        mMrtDefaultFragmentTexProgram = CreateFragmentProgram("mrt", "fragtex");
497
498        // provide the current view matrix
499        mMrtDefaultFragmentProgram->AddParameter("viewMatrix", 0);
500        mMrtDefaultFragmentTexProgram->AddParameter("viewMatrix", 0);
501        // add a texture parameter
502        mMrtDefaultFragmentTexProgram->AddParameter("tex", 1);
503
504
505        ////////////
506        //-- hack: apply hardcoded tree animation (should be provided with a material script!)
507
508        sTreeAnimationProgram = CreateVertexProgram("treeanimation", "animateVtx");
509        sTreeAnimationProgramMrt = CreateVertexProgram("treeanimation", "animateVtxMrt");
510
511        sTreeAnimationProgram->AddParameter("timer", 0);
512        sTreeAnimationProgram->AddParameter("windDir", 1);
513        sTreeAnimationProgram->AddParameter("windStrength", 2);
514        sTreeAnimationProgram->AddParameter("minMaxPos", 3);
515        sTreeAnimationProgram->AddParameter("frequency", 4);
516        sTreeAnimationProgram->AddParameter("lightDir", 5);
517
518        sTreeAnimationProgramMrt->AddParameter("timer", 0);
519        sTreeAnimationProgramMrt->AddParameter("windDir", 1);
520        sTreeAnimationProgramMrt->AddParameter("windStrength", 2);
521        sTreeAnimationProgramMrt->AddParameter("minMaxPos", 3);
522        sTreeAnimationProgramMrt->AddParameter("frequency", 4);
523
524        cout << "cg initialization successful" << endl;
525}
526
527
528void ResourceManager::EnableFragmentProfile()
529{
530        cgGLEnableProfile(sCgFragmentProfile);
531}
532
533
534void ResourceManager::EnableVertexProfile()
535{
536        cgGLEnableProfile(sCgVertexProfile);
537}
538
539
540void ResourceManager::DisableFragmentProfile()
541{
542        cgGLDisableProfile(sCgFragmentProfile);
543}
544
545
546void ResourceManager::DisableVertexProfile()
547{
548        cgGLDisableProfile(sCgVertexProfile);
549       
550}
551
552
553}
554
Note: See TracBrowser for help on using the repository browser.