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

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