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

Revision 3042, 11.6 KB checked in by mattausch, 16 years ago (diff)

added technique

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;
167                                Material *mat = shape->GetMaterial();
[3042]168                                Technique *tech = mat->GetDefaultTechnique();
169                               
170                                tech->SetVertexProgram(sTreeAnimation);
[3041]171
[3042]172                                GPUProgramParameters *vtxParams = tech->GetVertexProgramParameters();
[3041]173
174                                vtxParams->SetTimerParam(0);
175                                // wind direction
176                                static Vector3 windDir = Normalize(Vector3(0.8f, 0.2f, 0.0f));
177                                vtxParams->SetValue3f(1, windDir.x, windDir.y, windDir.z);
178                                // amplitude
179                                vtxParams->SetValue1f(2, 0.3f);
180
181                                AxisAlignedBox3 box = sceneGeom->GetBoundingBox();
182                                vtxParams->SetValue2f(3, box.Min().z, box.Max().z);
183                                // frequency
184                                vtxParams->SetValue1f(4, 0.1f);
185                        }
186                }
187        }
188
[2755]189        return sceneGeom;
[2747]190}
191
192
[2795]193void ResourceManager::LoadTextures(igzstream &str)
[2757]194{
195        int numTextures;
196        str.read(reinterpret_cast<char *>(&numTextures), sizeof(int));
[2961]197       
[2757]198        for (int i = 0; i < numTextures; ++ i)
199        {
[2961]200                // load texture name
[2757]201                int texnameSize;
202                str.read(reinterpret_cast<char *>(&texnameSize), sizeof(int));
203
204                char *texname = new char[texnameSize];
205                str.read(texname, sizeof(char) * texnameSize);
206
[2784]207                Texture *tex = new Texture(model_path + texname);
[2757]208
[2846]209                int boundS, boundT;
210
211                str.read(reinterpret_cast<char *>(&boundS), sizeof(int));
212                str.read(reinterpret_cast<char *>(&boundT), sizeof(int));
213
214                tex->SetBoundaryModeS(boundS);
215                tex->SetBoundaryModeT(boundT);
216
217                tex->Create();
218
[2764]219                mTextureTable[i] = tex;
[2795]220                mTextures.push_back(tex);
[3021]221
222                delete [] texname;
[2757]223        }
[2764]224
[2800]225        cout << "loaded " << (int)mTextureTable.size() << " textures" << endl;
[2757]226}
227
228
[2795]229void ResourceManager::LoadShapes(igzstream &str)
[2764]230{
231        int numShapes;
232        str.read(reinterpret_cast<char *>(&numShapes), sizeof(int));
233
234        for (int i = 0; i < numShapes; ++ i)
235        {
236                Geometry *geom = LoadGeometry(str);
237                Material *mat = LoadMaterial(str);
238
239                mGeometryTable[i] = geom;
[2842]240                mMaterialTable[i] = mat;               
[2795]241
242                mGeometry.push_back(geom);
243                mMaterials.push_back(mat);
[2764]244        }
245
[2800]246        cout << "loaded " << (int)mGeometryTable.size() << " shapes" << endl;
[2764]247}
248
249
[2795]250Material *ResourceManager::LoadMaterial(igzstream &str)
[2747]251{
[2756]252        // default material
[2755]253        Material *mat = new Material();
[2756]254       
[3042]255        // set default fragment + vertex programs
256        Technique *tech = mat->GetDefaultTechnique();
257
[2747]258        // texture
[2757]259        int texId;
260        str.read(reinterpret_cast<char *>(&texId), sizeof(int));
[2747]261
[2982]262        if (texId >= 0)
[3042]263                tech->SetTexture(mTextureTable[texId]);
[2764]264       
[3042]265        str.read(reinterpret_cast<char *>(&tech->mAlphaTestEnabled), sizeof(bool));
266        str.read(reinterpret_cast<char *>(&tech->mCullFaceEnabled), sizeof(bool));
[2844]267
[3034]268        // gl material
269        bool hasGlMaterial;
270        str.read(reinterpret_cast<char *>(&hasGlMaterial), sizeof(bool));
[3042]271
[3034]272        if (hasGlMaterial)
[2747]273        {
[2769]274                // only write rgb part of the material
[3042]275                str.read(reinterpret_cast<char *>(&tech->mAmbientColor), sizeof(Vector3));
276                str.read(reinterpret_cast<char *>(&tech->mDiffuseColor), sizeof(Vector3));
277                str.read(reinterpret_cast<char *>(&tech->mEmmisiveColor), sizeof(Vector3));
278                str.read(reinterpret_cast<char *>(&tech->mSpecularColor), sizeof(Vector3));
[2747]279        }
280
[3042]281        if (tech->GetTexture())
[3034]282        {
[3042]283                tech->mFragmentProgram = mMrtDefaultFragmentTexProgram;
[3034]284
[3042]285                tech->mGPUFragmentParameters = CreateGPUProgramParameters(tech->mFragmentProgram);
286                tech->mGPUFragmentParameters->SetTexture(0, tech->GetTexture()->GetId());
[3034]287        }       
288        else
289        {
[3042]290                tech->mFragmentProgram = mMrtDefaultFragmentProgram;
291                tech->mGPUFragmentParameters = CreateGPUProgramParameters(tech->mFragmentProgram);
[3034]292        }
293
[3042]294        tech->mVertexProgram = mMrtDefaultVertexProgram;
295        tech->mGPUVertexParameters = CreateGPUProgramParameters(tech->mVertexProgram);
[3041]296       
[2755]297        return mat;
[2747]298}
299
300
[2795]301Geometry *ResourceManager::LoadGeometry(igzstream &str)
[2747]302{
[2756]303        Vector3 *vertices;
304        Vector3 *normals;
[2980]305        Texcoord2 *texcoords;
[2747]306
307
[2756]308        //////////////
309        //-- read in vertices
[2747]310
[2756]311        int vertexCount;
312        str.read(reinterpret_cast<char *>(&vertexCount), sizeof(int));
[2747]313       
314        // end of file reached
[2961]315        if (str.eof()) return NULL;
[2747]316
[2757]317        //cout << "vertexcount: " << vertexCount << endl;
[2747]318
[2756]319        vertices = new Vector3[vertexCount];
320    str.read(reinterpret_cast<char *>(vertices), sizeof(Vector3) * vertexCount);
[2747]321       
[2756]322        normals = new Vector3[vertexCount];
323        str.read(reinterpret_cast<char *>(normals), sizeof(Vector3) * vertexCount);
[2747]324
[2756]325        int texCoordCount;
326        str.read(reinterpret_cast<char *>(&texCoordCount), sizeof(int));
[2747]327
[2756]328        if (texCoordCount)
[2747]329        {
[2980]330                texcoords = new Texcoord2[texCoordCount];
331                str.read(reinterpret_cast<char *>(texcoords), sizeof(Texcoord2) * texCoordCount);
[2747]332        }
[2756]333        else
[2811]334        {
[2756]335                texcoords = NULL;
[2811]336        }
[2747]337
[2982]338        return new Geometry(vertices, normals, texcoords, vertexCount, true);
339        //return new Geometry(vertices, normals, texcoords, vertexCount, false);
[2747]340}
341
342
[2795]343void ResourceManager::LoadSceneEntities(igzstream &str, SceneEntityContainer &entities)
[2747]344{
[2764]345        int entityCount;
346        str.read(reinterpret_cast<char *>(&entityCount), sizeof(int));
347
[2963]348        entities.reserve(entityCount);
[2764]349
350        for (int i = 0; i < entityCount; ++ i)
351        {
352                SceneEntity *ent = LoadSceneEntity(str);
[2842]353
[2963]354                // return loaded entities
355                entities.push_back(ent);
356                // also store internally
[2795]357                mSceneEntities.push_back(ent);
[2764]358        }
359
360        cout << "loaded " << entityCount << " scene entities" << endl;
361}
362
363
[2795]364bool ResourceManager::Load(const std::string &filename, SceneEntityContainer &entities)
[2764]365{
[2795]366        igzstream istr(filename.c_str());
[2747]367       
[2756]368        if (!istr.is_open())
[2747]369                return false;
370
[2764]371        cout << "loading textures" << endl;
372       
[2757]373        // load the texture table
374        LoadTextures(istr);
375
[2764]376        cout << "loading shapes (geometry + materials)" << endl;
[2747]377
[2764]378        // load the shapees
379        LoadShapes(istr);
[2762]380
[2764]381        cout << "loading scene entites" << endl;
382        LoadSceneEntities(istr, entities);
[2763]383       
[2756]384        cout << "bin loading finished" << endl;
[2747]385
[2795]386        // clean up
387        mTextureTable.clear();
388        mGeometryTable.clear();
389        mMaterialTable.clear();
390
[2756]391        return true;
[2747]392}
393
[3036]394
395GPUProgramParameters *ResourceManager::CreateGPUProgramParameters(ShaderProgram *p)
396{
397        GPUProgramParameters *gpuParams = new GPUProgramParameters(p);
398        mGPUParameters.push_back(gpuParams);
399
400        return gpuParams;
[2747]401}
[3036]402
[3037]403
[3038]404ShaderProgram *ResourceManager::CreateFragmentProgram(const std::string &filename, const std::string &funcName)
[3037]405{
[3038]406        const string fullName = "src/shaders/" + filename + ".cg";
407
408        ShaderProgram *p = new ShaderProgram(sCgContext, fullName, sCgFragmentProfile, funcName);
409
410        mShaders.push_back(p);
411
412        if (!p->IsValid())
413        {
414                DEL_PTR(p);
415                cerr << "Program " << funcName << " in " << fullName << " failed to load" << endl;
416        }
417       
418        cout << "Program " << funcName << " in " << fullName << " loaded" << endl;
419
[3037]420        return p;
[3036]421}
422
[3038]423
424ShaderProgram *ResourceManager::CreateVertexProgram(const std::string &filename, const std::string &funcName)
425{
426        const string fullName = "src/shaders/" + filename + ".cg";
427       
428        ShaderProgram *p = new ShaderProgram(sCgContext, fullName, sCgVertexProfile, funcName);
429        mShaders.push_back(p);
430
431        if (!p->IsValid())
432        {
433                DEL_PTR(p);
434                cerr << "Program " << funcName << " in " << fullName << " failed to load" << endl;
435        }
436       
437        cout << "Program " << funcName << " in " << fullName << " loaded" << endl;
438
439        return p;
[3037]440}
441
[3038]442
443void ResourceManager::InitCg()
444{
445        // setup cg
446        cgSetErrorCallback(cgErrorCallback);
447        // create context.
448        sCgContext = cgCreateContext();
449        // get the optimal fragment profile
450        sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
451        cgGLSetOptimalOptions(sCgFragmentProfile);
452        // get the optimal vertex profile
453        sCgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
454        cgGLSetOptimalOptions(sCgVertexProfile);
455
456        // set textures to auto load
457        cgGLSetManageTextureParameters(sCgContext, false);
458
459        mMrtDefaultVertexProgram = CreateVertexProgram("mrt", "vtx");
[3039]460        mMrtDefaultFragmentProgram = CreateFragmentProgram("mrt", "frag");
[3038]461        mMrtDefaultFragmentTexProgram = CreateFragmentProgram("mrt", "fragtex");
462        mMrtDefaultFragmentTexProgram->AddParameter("tex", 0);
463
[3041]464        sTreeAnimation = CreateVertexProgram("treeanimation", "animateVtx");
465
466        sTreeAnimation->AddParameter("timer", 0);
467        sTreeAnimation->AddParameter("windDir", 1);
468        sTreeAnimation->AddParameter("windStrength", 2);
469        sTreeAnimation->AddParameter("minMaxPos", 3);
470        sTreeAnimation->AddParameter("frequency", 4);
471
[3038]472        cout << "cg initialization successful" << endl;
473}
474
475
476void ResourceManager::EnableFragmentProfile()
477{
478        cgGLEnableProfile(sCgFragmentProfile);
479}
480
481
482void ResourceManager::EnableVertexProfile()
483{
484        cgGLEnableProfile(sCgVertexProfile);
485}
486
487
488void ResourceManager::DisableFragmentProfile()
489{
490        cgGLDisableProfile(sCgFragmentProfile);
491}
492
493
494void ResourceManager::DisableVertexProfile()
495{
496        cgGLDisableProfile(sCgVertexProfile);
497       
498}
499
500
501}
502
Note: See TracBrowser for help on using the repository browser.