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

Revision 3047, 12.8 KB checked in by mattausch, 16 years ago (diff)

adding special technique for depth pass (not working yet)

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