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

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;
44static ShaderProgram *sTreeAnimation;
45
46// only instance of the resource manager
47ResourceManager *ResourceManager::sResourceManager = NULL;
48
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
72ResourceManager::~ResourceManager()
73{
74        // delete all resources.
75        CLEAR_CONTAINER(mSceneEntities);
76        CLEAR_CONTAINER(mGeometry);
77        CLEAR_CONTAINER(mMaterials);
78        CLEAR_CONTAINER(mTextures);
79        CLEAR_CONTAINER(mTrafos);
80        CLEAR_CONTAINER(mShapes);
81        CLEAR_CONTAINER(mLODs);
82        CLEAR_CONTAINER(mGPUParameters);
83        CLEAR_CONTAINER(mShaders);
84       
85        if (sCgContext)
86                cgDestroyContext(sCgContext);
87}
88
89
90SceneEntity *ResourceManager::LoadSceneEntity(igzstream &str)
91{       
92        bool hasTrafo;
93        str.read(reinterpret_cast<char *>(&hasTrafo), sizeof(bool));
94       
95        SceneEntity *sceneGeom;
96        Transform3 *trafo;
97
98        if (!hasTrafo)
99        {
100                // identity
101                trafo = new Transform3();
102        }
103        else
104        {
105                Matrix4x4 m;
106                str.read(reinterpret_cast<char *>(m.x), sizeof(Matrix4x4));
107               
108                trafo = new Transform3(m);
109        }
110
111        mTrafos.push_back(trafo);
112
113        sceneGeom = new SceneEntity(trafo);
114
115
116        ///////////////
117        //-- load lod levels
118
119        // note: lods must be ordered from smallest distance to largest
120        int numLODs;
121        str.read(reinterpret_cast<char *>(&numLODs), sizeof(int));
122
123        for (int i = 0; i < numLODs; ++ i)
124        {
125                float dist;
126                str.read(reinterpret_cast<char *>(&dist), sizeof(float));
127
128                int numShapes;
129                str.read(reinterpret_cast<char *>(&numShapes), sizeof(int));
130
131                LODLevel *lodLevel = new LODLevel(dist);
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);
143
144                        mShapes.push_back(shape);
145
146                        sceneGeom->AddShape(shape);
147                        lodLevel->AddShape(shape);
148                }
149
150                mLODs.push_back(lodLevel);
151                sceneGeom->AddLODLevel(lodLevel);
152        }
153
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();
168                                Technique *tech = mat->GetDefaultTechnique();
169                               
170                                tech->SetVertexProgram(sTreeAnimation);
171
172                                GPUProgramParameters *vtxParams = tech->GetVertexProgramParameters();
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
189        return sceneGeom;
190}
191
192
193void ResourceManager::LoadTextures(igzstream &str)
194{
195        int numTextures;
196        str.read(reinterpret_cast<char *>(&numTextures), sizeof(int));
197       
198        for (int i = 0; i < numTextures; ++ i)
199        {
200                // load texture name
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
207                Texture *tex = new Texture(model_path + texname);
208
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
219                mTextureTable[i] = tex;
220                mTextures.push_back(tex);
221
222                delete [] texname;
223        }
224
225        cout << "loaded " << (int)mTextureTable.size() << " textures" << endl;
226}
227
228
229void ResourceManager::LoadShapes(igzstream &str)
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;
240                mMaterialTable[i] = mat;               
241
242                mGeometry.push_back(geom);
243                mMaterials.push_back(mat);
244        }
245
246        cout << "loaded " << (int)mGeometryTable.size() << " shapes" << endl;
247}
248
249
250Material *ResourceManager::LoadMaterial(igzstream &str)
251{
252        // default material
253        Material *mat = new Material();
254       
255        // set default fragment + vertex programs
256        Technique *tech = mat->GetDefaultTechnique();
257
258        // texture
259        int texId;
260        str.read(reinterpret_cast<char *>(&texId), sizeof(int));
261
262        if (texId >= 0)
263                tech->SetTexture(mTextureTable[texId]);
264       
265        str.read(reinterpret_cast<char *>(&tech->mAlphaTestEnabled), sizeof(bool));
266        str.read(reinterpret_cast<char *>(&tech->mCullFaceEnabled), sizeof(bool));
267
268        // gl material
269        bool hasGlMaterial;
270        str.read(reinterpret_cast<char *>(&hasGlMaterial), sizeof(bool));
271
272        if (hasGlMaterial)
273        {
274                // only write rgb part of the material
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));
279        }
280
281        if (tech->GetTexture())
282        {
283                tech->mFragmentProgram = mMrtDefaultFragmentTexProgram;
284
285                tech->mGPUFragmentParameters = CreateGPUProgramParameters(tech->mFragmentProgram);
286                tech->mGPUFragmentParameters->SetTexture(0, tech->GetTexture()->GetId());
287        }       
288        else
289        {
290                tech->mFragmentProgram = mMrtDefaultFragmentProgram;
291                tech->mGPUFragmentParameters = CreateGPUProgramParameters(tech->mFragmentProgram);
292        }
293
294        tech->mVertexProgram = mMrtDefaultVertexProgram;
295        tech->mGPUVertexParameters = CreateGPUProgramParameters(tech->mVertexProgram);
296       
297        return mat;
298}
299
300
301Geometry *ResourceManager::LoadGeometry(igzstream &str)
302{
303        Vector3 *vertices;
304        Vector3 *normals;
305        Texcoord2 *texcoords;
306
307
308        //////////////
309        //-- read in vertices
310
311        int vertexCount;
312        str.read(reinterpret_cast<char *>(&vertexCount), sizeof(int));
313       
314        // end of file reached
315        if (str.eof()) return NULL;
316
317        //cout << "vertexcount: " << vertexCount << endl;
318
319        vertices = new Vector3[vertexCount];
320    str.read(reinterpret_cast<char *>(vertices), sizeof(Vector3) * vertexCount);
321       
322        normals = new Vector3[vertexCount];
323        str.read(reinterpret_cast<char *>(normals), sizeof(Vector3) * vertexCount);
324
325        int texCoordCount;
326        str.read(reinterpret_cast<char *>(&texCoordCount), sizeof(int));
327
328        if (texCoordCount)
329        {
330                texcoords = new Texcoord2[texCoordCount];
331                str.read(reinterpret_cast<char *>(texcoords), sizeof(Texcoord2) * texCoordCount);
332        }
333        else
334        {
335                texcoords = NULL;
336        }
337
338        return new Geometry(vertices, normals, texcoords, vertexCount, true);
339        //return new Geometry(vertices, normals, texcoords, vertexCount, false);
340}
341
342
343void ResourceManager::LoadSceneEntities(igzstream &str, SceneEntityContainer &entities)
344{
345        int entityCount;
346        str.read(reinterpret_cast<char *>(&entityCount), sizeof(int));
347
348        entities.reserve(entityCount);
349
350        for (int i = 0; i < entityCount; ++ i)
351        {
352                SceneEntity *ent = LoadSceneEntity(str);
353
354                // return loaded entities
355                entities.push_back(ent);
356                // also store internally
357                mSceneEntities.push_back(ent);
358        }
359
360        cout << "loaded " << entityCount << " scene entities" << endl;
361}
362
363
364bool ResourceManager::Load(const std::string &filename, SceneEntityContainer &entities)
365{
366        igzstream istr(filename.c_str());
367       
368        if (!istr.is_open())
369                return false;
370
371        cout << "loading textures" << endl;
372       
373        // load the texture table
374        LoadTextures(istr);
375
376        cout << "loading shapes (geometry + materials)" << endl;
377
378        // load the shapees
379        LoadShapes(istr);
380
381        cout << "loading scene entites" << endl;
382        LoadSceneEntities(istr, entities);
383       
384        cout << "bin loading finished" << endl;
385
386        // clean up
387        mTextureTable.clear();
388        mGeometryTable.clear();
389        mMaterialTable.clear();
390
391        return true;
392}
393
394
395GPUProgramParameters *ResourceManager::CreateGPUProgramParameters(ShaderProgram *p)
396{
397        GPUProgramParameters *gpuParams = new GPUProgramParameters(p);
398        mGPUParameters.push_back(gpuParams);
399
400        return gpuParams;
401}
402
403
404ShaderProgram *ResourceManager::CreateFragmentProgram(const std::string &filename, const std::string &funcName)
405{
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
420        return p;
421}
422
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;
440}
441
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");
460        mMrtDefaultFragmentProgram = CreateFragmentProgram("mrt", "frag");
461        mMrtDefaultFragmentTexProgram = CreateFragmentProgram("mrt", "fragtex");
462        mMrtDefaultFragmentTexProgram->AddParameter("tex", 0);
463
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
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.