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

Revision 3045, 11.5 KB checked in by mattausch, 16 years ago (diff)
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
168                                Material *mat = shape->GetMaterial();
169
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);
175
176                                        GPUProgramParameters *vtxParams = tech->GetVertexProgramParameters();
177
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                                }
190                        }
191                }
192        }
193
194        return sceneGeom;
195}
196
197
198void ResourceManager::LoadTextures(igzstream &str)
199{
200        int numTextures;
201        str.read(reinterpret_cast<char *>(&numTextures), sizeof(int));
202       
203        for (int i = 0; i < numTextures; ++ i)
204        {
205                // load texture name
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
212                Texture *tex = new Texture(model_path + texname);
213
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
224                mTextureTable[i] = tex;
225                mTextures.push_back(tex);
226
227                delete [] texname;
228        }
229
230        cout << "loaded " << (int)mTextureTable.size() << " textures" << endl;
231}
232
233
234void ResourceManager::LoadShapes(igzstream &str)
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;
245                mMaterialTable[i] = mat;               
246
247                mGeometry.push_back(geom);
248                mMaterials.push_back(mat);
249        }
250
251        cout << "loaded " << (int)mGeometryTable.size() << " shapes" << endl;
252}
253
254
255Material *ResourceManager::LoadMaterial(igzstream &str)
256{
257        // default material
258        Material *mat = new Material();
259       
260        // set default fragment + vertex programs
261        Technique *tech = mat->GetDefaultTechnique();
262
263        // texture
264        int texId;
265        str.read(reinterpret_cast<char *>(&texId), sizeof(int));
266
267        if (texId >= 0)
268                tech->SetTexture(mTextureTable[texId]);
269       
270        str.read(reinterpret_cast<char *>(&tech->mAlphaTestEnabled), sizeof(bool));
271        str.read(reinterpret_cast<char *>(&tech->mCullFaceEnabled), sizeof(bool));
272
273        // gl material
274        bool hasGlMaterial;
275        str.read(reinterpret_cast<char *>(&hasGlMaterial), sizeof(bool));
276
277        if (hasGlMaterial)
278        {
279                // only write rgb part of the material
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));
284        }
285
286
287        ///////////////
288        //-- add technique for deferred shading
289
290        Technique *deferred = new Technique(*tech);
291
292        if (deferred->GetTexture())
293        {
294                deferred->SetFragmentProgram(mMrtDefaultFragmentTexProgram);
295                deferred->GetFragmentProgramParameters()->SetTexture(0, tech->GetTexture()->GetId());
296        }       
297        else
298        {
299                deferred->SetFragmentProgram(mMrtDefaultFragmentProgram);
300        }
301
302        deferred->SetVertexProgram(mMrtDefaultVertexProgram);
303       
304        mat->AddTechnique(deferred);
305
306        return mat;
307}
308
309
310Geometry *ResourceManager::LoadGeometry(igzstream &str)
311{
312        Vector3 *vertices;
313        Vector3 *normals;
314        Texcoord2 *texcoords;
315
316
317        //////////////
318        //-- read in vertices
319
320        int vertexCount;
321        str.read(reinterpret_cast<char *>(&vertexCount), sizeof(int));
322       
323        // end of file reached
324        if (str.eof()) return NULL;
325
326        //cout << "vertexcount: " << vertexCount << endl;
327
328        vertices = new Vector3[vertexCount];
329    str.read(reinterpret_cast<char *>(vertices), sizeof(Vector3) * vertexCount);
330       
331        normals = new Vector3[vertexCount];
332        str.read(reinterpret_cast<char *>(normals), sizeof(Vector3) * vertexCount);
333
334        int texCoordCount;
335        str.read(reinterpret_cast<char *>(&texCoordCount), sizeof(int));
336
337        if (texCoordCount)
338        {
339                texcoords = new Texcoord2[texCoordCount];
340                str.read(reinterpret_cast<char *>(texcoords), sizeof(Texcoord2) * texCoordCount);
341        }
342        else
343        {
344                texcoords = NULL;
345        }
346
347        return new Geometry(vertices, normals, texcoords, vertexCount, true);
348        //return new Geometry(vertices, normals, texcoords, vertexCount, false);
349}
350
351
352void ResourceManager::LoadSceneEntities(igzstream &str, SceneEntityContainer &entities)
353{
354        int entityCount;
355        str.read(reinterpret_cast<char *>(&entityCount), sizeof(int));
356
357        entities.reserve(entityCount);
358
359        for (int i = 0; i < entityCount; ++ i)
360        {
361                SceneEntity *ent = LoadSceneEntity(str);
362
363                // return loaded entities
364                entities.push_back(ent);
365                // also store internally
366                mSceneEntities.push_back(ent);
367        }
368
369        cout << "loaded " << entityCount << " scene entities" << endl;
370}
371
372
373bool ResourceManager::Load(const std::string &filename, SceneEntityContainer &entities)
374{
375        igzstream istr(filename.c_str());
376       
377        if (!istr.is_open())
378                return false;
379
380        cout << "loading textures" << endl;
381       
382        // load the texture table
383        LoadTextures(istr);
384
385        cout << "loading shapes (geometry + materials)" << endl;
386
387        // load the shapees
388        LoadShapes(istr);
389
390        cout << "loading scene entites" << endl;
391        LoadSceneEntities(istr, entities);
392       
393        cout << "bin loading finished" << endl;
394
395        // clean up
396        mTextureTable.clear();
397        mGeometryTable.clear();
398        mMaterialTable.clear();
399
400        return true;
401}
402
403
404
405ShaderProgram *ResourceManager::CreateFragmentProgram(const std::string &filename,
406                                                                                                          const std::string &funcName)
407{
408        const string fullName = "src/shaders/" + filename + ".cg";
409
410        ShaderProgram *p = new ShaderProgram(sCgContext, fullName, sCgFragmentProfile, funcName);
411
412        mShaders.push_back(p);
413
414        if (!p->IsValid())
415        {
416                DEL_PTR(p);
417                cerr << "Program " << funcName << " in " << fullName << " failed to load" << endl;
418        }
419       
420        cout << "Program " << funcName << " in " << fullName << " loaded" << endl;
421
422        return p;
423}
424
425
426ShaderProgram *ResourceManager::CreateVertexProgram(const std::string &filename, const std::string &funcName)
427{
428        const string fullName = "src/shaders/" + filename + ".cg";
429       
430        ShaderProgram *p = new ShaderProgram(sCgContext, fullName, sCgVertexProfile, funcName);
431        mShaders.push_back(p);
432
433        if (!p->IsValid())
434        {
435                DEL_PTR(p);
436                cerr << "Program " << funcName << " in " << fullName << " failed to load" << endl;
437        }
438       
439        cout << "Program " << funcName << " in " << fullName << " loaded" << endl;
440
441        return p;
442}
443
444
445void ResourceManager::InitCg()
446{
447        // setup cg
448        cgSetErrorCallback(cgErrorCallback);
449        // create context.
450        sCgContext = cgCreateContext();
451        // get the optimal fragment profile
452        sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
453        cgGLSetOptimalOptions(sCgFragmentProfile);
454        // get the optimal vertex profile
455        sCgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
456        cgGLSetOptimalOptions(sCgVertexProfile);
457
458        // set textures to auto load
459        cgGLSetManageTextureParameters(sCgContext, false);
460
461        mMrtDefaultVertexProgram = CreateVertexProgram("mrt", "vtx");
462        mMrtDefaultFragmentProgram = CreateFragmentProgram("mrt", "frag");
463        mMrtDefaultFragmentTexProgram = CreateFragmentProgram("mrt", "fragtex");
464        mMrtDefaultFragmentTexProgram->AddParameter("tex", 0);
465
466        sTreeAnimation = CreateVertexProgram("treeanimation", "animateVtxMrt");
467
468        sTreeAnimation->AddParameter("timer", 0);
469        sTreeAnimation->AddParameter("windDir", 1);
470        sTreeAnimation->AddParameter("windStrength", 2);
471        sTreeAnimation->AddParameter("minMaxPos", 3);
472        sTreeAnimation->AddParameter("frequency", 4);
473
474        cout << "cg initialization successful" << endl;
475}
476
477
478void ResourceManager::EnableFragmentProfile()
479{
480        cgGLEnableProfile(sCgFragmentProfile);
481}
482
483
484void ResourceManager::EnableVertexProfile()
485{
486        cgGLEnableProfile(sCgVertexProfile);
487}
488
489
490void ResourceManager::DisableFragmentProfile()
491{
492        cgGLDisableProfile(sCgFragmentProfile);
493}
494
495
496void ResourceManager::DisableVertexProfile()
497{
498        cgGLDisableProfile(sCgVertexProfile);
499       
500}
501
502
503}
504
Note: See TracBrowser for help on using the repository browser.