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

Revision 3046, 12.7 KB checked in by mattausch, 16 years ago (diff)

added shader for forward shadin tree animation program

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