0001: // ----------------------------------------------------------------------------
0002: //
0003: // main.cpp - GLUT のサンプルソース
0004: // 
0005: // Copyright (c) 2002 今給黎 隆 (imagire@nify.com)
0006: // All Rights Reserved.
0007: //
0008: // ----------------------------------------------------------------------------
0009: 
0010: #include <GL/glut.h>
0011: #include <Cg/cg.h>
0012: #include <Cg/cgGL.h>
0013: #include <assert.h>
0014: #include "CBitmap.h"
0015: 
0016: const char *TITLE = "Wave";
0017: 
0018: //テクスチャ
0019: const int TEX_SIZE = 128;
0020: unsigned int tex_wave;          // 波の生成
0021: unsigned int tex_normal;        // 法線マップの生成
0022: unsigned int tex_sky;           // 背景のテクスチャ
0023: 
0024: // Cg のオブジェクト
0025: static cgContext        *WaveCgContext              = NULL;
0026: static cgProgramIter    *WaveFragmentProgramIter    = NULL;
0027: static cgBindIter       *WaveTexBind                = NULL;
0028: 
0029: static cgContext        *NormalCgContext            = NULL;
0030: static cgProgramIter    *NormalFragmentProgramIter  = NULL;
0031: static cgBindIter       *NormalTexBind              = NULL;
0032: 
0033: static cgContext        *CgContext              = NULL;
0034: static cgProgramIter    *VertexProgramIter      = NULL;
0035: static cgBindIter       *WPMatrix               = NULL;
0036: static cgBindIter       *EyePos                 = NULL;
0037: static cgBindIter       *LightPos               = NULL;
0038: static cgProgramIter    *FragmentProgramIter    = NULL;
0039: static cgBindIter       *TexBind                = NULL;
0040: 
0041: // ---------------------------------------------------------------------------
0042: // 浮動小数点数乱数
0043: // ---------------------------------------------------------------------------
0044: #define frand() ((float)rand() / (float) RAND_MAX)
0045: // ---------------------------------------------------------------------------
0046: // 画面描画
0047: // ---------------------------------------------------------------------------
0048: static void draw_polygone()
0049: {
0050:     glBegin(GL_TRIANGLE_STRIP);     // ストリップ設定
0051:         glTexCoord2f(1.0, 0.0);
0052:         glVertex3f(+1.0, -1.0, 0.0f);
0053: 
0054:         glTexCoord2f(0.0, 0.0);
0055:         glVertex3f(-1.0, -1.0, 0.0f);
0056:         
0057:         glTexCoord2f(1.0, 1.0);
0058:         glVertex3f(+1.0, +1.0, 0.0f);
0059:         
0060:         glTexCoord2f(0.0, 1.0);
0061:         glVertex3f(-1.0, +1.0, 0.0f);
0062:     glEnd();                        // ポリゴンの描画終了
0063: }
0064: static void draw_sky()
0065: {
0066:     // テクスチャの設定
0067:     glEnable(GL_TEXTURE_2D);
0068:     glBindTexture(GL_TEXTURE_2D, tex_sky);
0069: 
0070:     glBegin(GL_TRIANGLE_STRIP);     // ストリップ設定
0071:         glTexCoord2f(0.0, 1.0);
0072:         glVertex3f(+5.0f,-1.0f, -5.0f);
0073: 
0074:         glTexCoord2f(1.0, 1.0);
0075:         glVertex3f(-5.0f,-1.0f, -5.0f);
0076:         
0077:         glTexCoord2f(0.0, 0.0);
0078:         glVertex3f(+5.0f, 4.0f, -5.0f);
0079:         
0080:         glTexCoord2f(1.0, 0.0);
0081:         glVertex3f(-5.0f, 4.0f, -5.0f);
0082:     glEnd();                        // ポリゴンの描画終了
0083: 
0084:     glDisable(GL_TEXTURE_2D);
0085: }
0086: // ---------------------------------------------------------------------------
0087: // 画面描画
0088: // ---------------------------------------------------------------------------
0089: void display(void)
0090: {
0091:     cgError Ret;
0092:     GLint   tmpview[4];
0093: 
0094:     glClearColor(0.0, 0.0, 0.3, 0.0);   // 背景色の設定
0095:     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
0096: 
0097:     glGetIntegerv(GL_VIEWPORT,tmpview); // ビューポートの保存
0098:     glViewport(0,0,TEX_SIZE,TEX_SIZE);  // 新しいビューポートの設定
0099: 
0100:     // 射影行列の設定
0101:     glMatrixMode(GL_PROJECTION);
0102:     glLoadIdentity();
0103:     glOrtho(-1,1, -1,1, 0.1,10);
0104:     
0105:     // ビュー行列の設定
0106:     glMatrixMode(GL_MODELVIEW);
0107:     glLoadIdentity();
0108:     gluLookAt(  0.0, 0.0, 1.0,      // 視点
0109:                 0.0, 0.0, 0.0,      // 注目点
0110:                 0.0, 1.0, 0.0);     // 上方向
0111: 
0112:     Ret = cgGLBindProgram(WaveFragmentProgramIter);
0113:     assert(Ret == cgNoError);
0114:     cgGLEnableProgramType(cgFragmentProfile);
0115: 
0116:     // テクスチャの使用
0117:     cgGLActiveTexture(WaveTexBind);
0118:     glEnable(GL_TEXTURE_2D);
0119:     glBindTexture(GL_TEXTURE_2D, tex_wave);
0120: 
0121:     glPushMatrix();                 // ビュー行列が他のポリゴンでも使えるよう退避
0122:     draw_polygone();                // ポリゴン描画
0123:     glPopMatrix();                  // ビュー行列に現在の行列を戻す
0124: 
0125:     //  テクスチャに転送
0126:     glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,0,0,TEX_SIZE,TEX_SIZE,0);
0127: 
0128:     // テクスチャ使わない
0129:     cgGLActiveTexture(WaveTexBind);
0130:     glDisable(GL_TEXTURE_2D);
0131:     // シェーダの無効化
0132:     cgGLDisableProgramType(cgFragmentProfile);
0133: 
0134:     // -----------------------------------------------------------------------
0135:     // 法線マップの作成
0136:     // -----------------------------------------------------------------------
0137:     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
0138: 
0139:     Ret = cgGLBindProgram(NormalFragmentProgramIter);
0140:     assert(Ret == cgNoError);
0141:     cgGLEnableProgramType(cgFragmentProfile);
0142: 
0143:     // テクスチャの使用
0144:     cgGLActiveTexture(NormalTexBind);
0145:     glEnable(GL_TEXTURE_2D);
0146:     glBindTexture(GL_TEXTURE_2D, tex_wave);
0147: 
0148:     glPushMatrix();                 // ビュー行列が他のポリゴンでも使えるよう退避
0149:     draw_polygone();                // ポリゴン描画
0150:     glPopMatrix();                  // ビュー行列に現在の行列を戻す
0151: 
0152:     // テクスチャ使わないよ
0153:     cgGLActiveTexture(NormalTexBind);
0154:     glDisable(GL_TEXTURE_2D);
0155: 
0156:     //  テクスチャに転送
0157:     glEnable(GL_TEXTURE_2D);
0158:     glBindTexture(GL_TEXTURE_2D, tex_normal);
0159:     glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,0,0,TEX_SIZE,TEX_SIZE,0);
0160:     glDisable(GL_TEXTURE_2D);
0161: 
0162:     // シェーダの無効化
0163:     cgGLDisableProgramType(cgFragmentProfile);
0164: 
0165:     // -----------------------------------------------------------------------
0166:     // シーンのレンダリング
0167:     // -----------------------------------------------------------------------
0168: 
0169:     // ビューポートを戻す
0170:     glViewport(tmpview[0],tmpview[1],tmpview[2],tmpview[3]);
0171:     // 背景色の設定
0172:     glClearColor(0.51, 0.29, 0.17, 0.0);
0173:     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
0174: 
0175:     // 射影行列の設定
0176:     glMatrixMode(GL_PROJECTION);
0177:     glLoadIdentity();
0178:     gluPerspective( 50.0,           // 画角
0179:                     1.0,            // アスペクト比
0180:                     0.1, 10.0);     // 前方面、後方面
0181: 
0182:     // ビュー行列の設定
0183:     glMatrixMode(GL_MODELVIEW);
0184:     glLoadIdentity();
0185:     gluLookAt(  0.0, 2.0, 5.0,      // 視点
0186:                 0.0, 0.0, 0.0,      // 注目点
0187:                 0.0, 1.0, 0.0);     // 上方向
0188:     // 背景の描画
0189:     draw_sky();
0190: 
0191:     // -----------------------------------------------------------------------
0192:     // Cg による描画へ切り替え
0193:     // -----------------------------------------------------------------------
0194: 
0195:     Ret = cgGLBindProgram(VertexProgramIter);
0196:     assert(Ret == cgNoError);
0197:     cgGLEnableProgramType(cgVertexProfile);
0198: 
0199:     Ret = cgGLBindProgram(FragmentProgramIter);
0200:     assert(Ret == cgNoError);
0201:     cgGLEnableProgramType(cgFragmentProfile);
0202: 
0203:     // テクスチャの使用
0204:     cgGLActiveTexture(TexBind);
0205:     glEnable(GL_TEXTURE_2D);
0206:     glBindTexture(GL_TEXTURE_2D, tex_normal);
0207: 
0208:     // local ⇒ proj
0209:     cgGLBindUniformStateMatrix(VertexProgramIter, WPMatrix, 
0210:         cgGLModelViewProjectionMatrix, cgGLMatrixIdentity);
0211: 
0212:     cgGLBindUniform4f(VertexProgramIter, EyePos,   0.0, 1.0,  5.0, 0.0);
0213:     cgGLBindUniform4f(VertexProgramIter, LightPos, 2.75, 2.0,-10.0, 0.0);
0214:     glBegin(GL_TRIANGLE_STRIP);     // ストリップ設定
0215:         glTexCoord2f(1.0, 0.0);
0216:         glVertex3f(+5.0f, 0.0f, -5.0);
0217: 
0218:         glTexCoord2f(0.0, 0.0);
0219:         glVertex3f(-5.0f, 0.0f, -5.0f);
0220:         
0221:         glTexCoord2f(1.0, 1.0);
0222:         glVertex3f(+5.0f, 0.0f, +5.0f);
0223:         
0224:         glTexCoord2f(0.0, 1.0);
0225:         glVertex3f(-5.0f, 0.0f, +5.0f);
0226:     glEnd();                        // ポリゴンの描画終了
0227:     glDisable(GL_TEXTURE_2D);
0228: 
0229:     cgGLActiveTexture(TexBind);
0230:     cgGLDisableProgramType(cgFragmentProfile);
0231:     cgGLDisableProgramType(cgVertexProfile);
0232: 
0233: 
0234: #if 1 // デバッグ用、画面の表示
0235: 
0236:     // 射影行列の設定
0237:     glMatrixMode(GL_PROJECTION);
0238:     glLoadIdentity();
0239:     glOrtho(-1,1, -1,1, 0.1,10);
0240:     
0241:     // ビュー行列の設定
0242:     glMatrixMode(GL_MODELVIEW);
0243:     glLoadIdentity();
0244:     gluLookAt(  0.0, 0.0, 1.0,      // 視点
0245:                 0.0, 0.0, 0.0,      // 注目点
0246:                 0.0, 1.0, 0.0);     // 上方向
0247: 
0248:     // テクスチャありで板ポリ描画
0249:     glEnable(GL_TEXTURE_2D);
0250:     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
0251:     glBindTexture(GL_TEXTURE_2D, tex_wave);
0252: 
0253:     glPushMatrix();
0254:         glBegin(GL_QUADS);
0255:         glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  0.5, 0.0);
0256:         glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, 0.0);
0257:         glTexCoord2f(1.0, 1.0); glVertex3f(-0.5,  1.0, 0.0);
0258:         glTexCoord2f(1.0, 0.0); glVertex3f(-0.5,  0.5, 0.0);
0259:         glEnd();
0260:     glPopMatrix();
0261:     glDisable(GL_TEXTURE_2D);
0262: 
0263:     glEnable(GL_TEXTURE_2D);
0264:     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
0265:     glBindTexture(GL_TEXTURE_2D, tex_normal);
0266:     glPushMatrix();
0267:         glBegin(GL_QUADS);
0268:         glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  0.0, 0.0);
0269:         glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  0.5, 0.0);
0270:         glTexCoord2f(1.0, 1.0); glVertex3f(-0.5,  0.5, 0.0);
0271:         glTexCoord2f(1.0, 0.0); glVertex3f(-0.5,  0.0, 0.0);
0272:         glEnd();
0273:     glPopMatrix();
0274:     glDisable(GL_TEXTURE_2D);
0275: 
0276: #endif
0277: 
0278:     // 画面の更新の終了
0279:     glutSwapBuffers();
0280: }
0281: // ---------------------------------------------------------------------------
0282: // 画面がリサイズされたとき
0283: // ---------------------------------------------------------------------------
0284: void resize(int w, int h)
0285: {
0286: }
0287: // ---------------------------------------------------------------------------
0288: // ひまなときに実行される
0289: // ---------------------------------------------------------------------------
0290: void idle()
0291: {
0292:     glutPostRedisplay();            // 再描画リクエスト
0293: }
0294: // ---------------------------------------------------------------------------
0295: // Cgの初期化
0296: // ---------------------------------------------------------------------------
0297: static void InitializeCg()
0298: {
0299:     cgError Ret;
0300:     
0301:     // -----------------------------------------------------------------------
0302:     // 波の動き
0303:     // -----------------------------------------------------------------------
0304:     // Cg の作成
0305:     WaveCgContext = cgCreateContext();
0306:     assert(WaveCgContext != NULL);
0307:     // フラグメントプログラム
0308:     Ret = cgAddProgramFromFile(WaveCgContext, "wave.cg", cgFragmentProfile, NULL);
0309:     assert(Ret == cgNoError);
0310: 
0311:     // プログラム名でプログラムを結びつける
0312:     WaveFragmentProgramIter = cgProgramByName(WaveCgContext, "main");
0313:     assert(WaveFragmentProgramIter != NULL);
0314: 
0315: #if 1
0316:     // ソースの表示
0317:     fprintf(stderr, "---- プログラム はじめ ----\n"
0318:                     "%s"
0319:                     "---- プログラム 終わり ----\n",
0320:     cgGetProgramObjectCode(WaveFragmentProgramIter));
0321: #endif
0322:     if(WaveFragmentProgramIter != NULL) {
0323:         GLuint ProgId = 1;
0324: 
0325:         Ret = cgGLLoadProgram(WaveFragmentProgramIter, ProgId);
0326:         assert(Ret == cgNoError);
0327: 
0328:         WaveTexBind     = cgGetBindByName(WaveFragmentProgramIter, "SrcTex");
0329:         assert(WaveTexBind != NULL);
0330:     }
0331:     
0332:     // -----------------------------------------------------------------------
0333:     // 法線マップの作成
0334:     // -----------------------------------------------------------------------
0335:     // Cg の作成
0336:     NormalCgContext = cgCreateContext();
0337:     assert(NormalCgContext != NULL);
0338:     // フラグメントプログラム
0339:     Ret = cgAddProgramFromFile(NormalCgContext, "normal.cg", cgFragmentProfile, NULL);
0340:     assert(Ret == cgNoError);
0341: 
0342:     // プログラム名でプログラムを結びつける
0343:     NormalFragmentProgramIter = cgProgramByName(NormalCgContext, "main");
0344:     assert(NormalFragmentProgramIter != NULL);
0345: 
0346: #if 1
0347:     // ソースの表示
0348:     fprintf(stderr, "---- プログラム はじめ ----\n"
0349:                     "%s"
0350:                     "---- プログラム 終わり ----\n",
0351:     cgGetProgramObjectCode(NormalFragmentProgramIter));
0352: #endif
0353:     if(NormalFragmentProgramIter != NULL) {
0354:         GLuint ProgId = 2;
0355: 
0356:         Ret = cgGLLoadProgram(NormalFragmentProgramIter, ProgId);
0357:         assert(Ret == cgNoError);
0358: 
0359:         NormalTexBind   = cgGetBindByName(NormalFragmentProgramIter, "SrcTex");
0360:         assert(NormalTexBind != NULL);
0361:     }
0362:     // -----------------------------------------------------------------------
0363:     // 波の表示
0364:     // -----------------------------------------------------------------------
0365:     // Cg の作成
0366:     CgContext = cgCreateContext();
0367:     assert(CgContext != NULL);
0368:     
0369:     // 頂点プログラム
0370:     Ret = cgAddProgramFromFile(CgContext, "vp.cg", cgVertexProfile, NULL);
0371:     assert(Ret == cgNoError);
0372:     // プログラム名でプログラムを結びつける
0373:     VertexProgramIter = cgProgramByName(CgContext, "main");
0374:     assert(VertexProgramIter != NULL);
0375: #if 1
0376:     // ソースの表示
0377:     fprintf(stderr, "---- プログラム はじめ ----\n"
0378:                     "%s"
0379:                     "---- プログラム 終わり ----\n",
0380:     cgGetProgramObjectCode(VertexProgramIter));
0381: #endif
0382:      if(VertexProgramIter != NULL) {
0383:          GLuint ProgId = 3;
0384:  
0385:          Ret = cgGLLoadProgram(VertexProgramIter, ProgId);
0386:          assert(Ret == cgNoError);
0387:  
0388:          EyePos    = cgGetBindByName(VertexProgramIter, "EyePos");
0389:          LightPos  = cgGetBindByName(VertexProgramIter, "LightPos");
0390:          WPMatrix  = cgGetBindByName(VertexProgramIter, "ModelViewProj");
0391:  
0392:          // エラーチェック
0393:          assert(EyePos != NULL);
0394:          assert(LightPos != NULL);
0395:          assert(WPMatrix != NULL);
0396:      }
0397: 
0398:     // フラグメントプログラム
0399:     Ret = cgAddProgramFromFile(CgContext, "fp.cg", cgFragmentProfile, NULL);
0400:     assert(Ret == cgNoError);
0401: 
0402:     // プログラム名でプログラムを結びつける
0403:     FragmentProgramIter = cgProgramByName(CgContext, "main");
0404:     assert(FragmentProgramIter != NULL);
0405: 
0406: #if 1
0407:     // ソースの表示
0408:     fprintf(stderr, "---- プログラム はじめ ----\n"
0409:                     "%s"
0410:                     "---- プログラム 終わり ----\n",
0411:     cgGetProgramObjectCode(FragmentProgramIter));
0412: #endif
0413:     if(FragmentProgramIter != NULL) {
0414:         GLuint ProgId = 4;
0415: 
0416:         Ret = cgGLLoadProgram(FragmentProgramIter, ProgId);
0417:         assert(Ret == cgNoError);
0418: 
0419:         TexBind     = cgGetBindByName(FragmentProgramIter, "SrcTex");
0420:         assert(TexBind != NULL);
0421:     }
0422:     
0423: }
0424: // ---------------------------------------------------------------------------
0425: // メイン関数
0426: // ---------------------------------------------------------------------------
0427: int main(int argc, char *argv[])
0428: {
0429:     int i, j;
0430: 
0431:     // ウィンドウの作成
0432:     glutInitWindowPosition(100, 100);   // 表示位置
0433:     glutInitWindowSize(512, 512);       // サイズ
0434:     glutInit(&argc, argv);              // GLの初期化
0435:     glutInitDisplayMode(GLUT_DOUBLE     // 描画モード
0436:                      | GLUT_RGBA        // wバッファ+RGBA+深度バッファ
0437:                      | GLUT_DEPTH);
0438:     glutCreateWindow(TITLE);            // ウィンドウの生成
0439:     
0440:     // コールバック関数の設定
0441:     glutDisplayFunc(display);           // 描画関数
0442:     glutReshapeFunc(resize);    // 画面が変形したとき
0443:     glutIdleFunc(idle);         // ひまなとき
0444:     
0445:     // Cg の初期化
0446:     InitializeCg();
0447: 
0448:     //テクスチャの生成
0449:     GLubyte image[TEX_SIZE][TEX_SIZE][4];
0450:     for(i=0;i<TEX_SIZE;i++){
0451:     for(j=0;j<TEX_SIZE;j++){
0452:         image[i][j][0] = 255.9f*frand();
0453:         image[i][j][1] = 255.9f*frand();
0454:     }
0455:     }
0456:     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
0457:     glGenTextures(1, &tex_wave);
0458:     glBindTexture(GL_TEXTURE_2D, tex_wave);
0459:     glTexImage2D(GL_TEXTURE_2D, 0
0460:         , 4         // Layer 数
0461:         , TEX_SIZE  // width
0462:         , TEX_SIZE  // height
0463:         , 0         // 境界線の幅
0464:         , GL_RGBA, GL_UNSIGNED_BYTE, image); 
0465:     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
0466:     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
0467:     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
0468:     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
0469:     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 
0470:     glEnable(GL_TEXTURE_2D);
0471: 
0472:     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
0473:     glGenTextures(1, &tex_normal);
0474:     glBindTexture(GL_TEXTURE_2D, tex_normal);
0475:     glTexImage2D(GL_TEXTURE_2D, 0
0476:         , 4         // Layer 数
0477:         , TEX_SIZE  // width
0478:         , TEX_SIZE  // height
0479:         , 0         // 境界線の幅
0480:         , GL_RGBA, GL_UNSIGNED_BYTE, image); 
0481:     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
0482:     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
0483:     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
0484:     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
0485:     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 
0486:     glEnable(GL_TEXTURE_2D);
0487:     
0488:     tex_sky = CBitmap::Load("sky.bmp");
0489:     glBindTexture(GL_TEXTURE_2D, tex_sky);
0490:     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
0491:     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
0492:     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
0493:     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
0494:     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
0495: 
0496:     // 一度だけすればいい設定
0497:     glEnable(GL_DEPTH_TEST);            // 深度バッファの使用
0498: 
0499:     glutMainLoop();                     // メインループ
0500: 
0501:     if( TexBind )cgFreeBindIter( TexBind );
0502:     cgFreeProgramIter( FragmentProgramIter );
0503:     if( EyePos     )cgFreeBindIter( EyePos );
0504:     if( LightPos   )cgFreeBindIter( LightPos );
0505:     if( WPMatrix   )cgFreeBindIter( WPMatrix );
0506:     cgFreeProgramIter( VertexProgramIter );
0507: 
0508:     if( WaveTexBind )cgFreeBindIter( WaveTexBind );
0509:     cgFreeProgramIter( WaveFragmentProgramIter );
0510: 
0511:     if( NormalTexBind )cgFreeBindIter( NormalTexBind );
0512:     cgFreeProgramIter( NormalFragmentProgramIter );
0513: 
0514:     cgFreeContext( CgContext );
0515:     cgFreeContext( NormalCgContext );
0516:     cgFreeContext( WaveCgContext );
0517:     cgCleanup( );
0518: 
0519:     return 0;
0520: }