0001:
0002:
0003:
0004:
0005:
0006:
0007:
0008:
0009: #define GLH_EXT_SINGLE_FILE
0010: #ifdef _WIN32
0011: #pragma warning (disable:4786)
0012: #endif
0013: #pragma warning (disable:4267)
0014:
0015: #include <math.h>
0016: #include <stdio.h>
0017: #include <assert.h>
0018: #include <GL/glut.h>
0019: #include <Cg/cg.h>
0020: #include <Cg/cgGL.h>
0021: #include <glh_glut.h>
0022: #include "matrix.h"
0023: #include "noise.h"
0024:
0025:
0026:
0027:
0028:
0029: static float r = 0.0f;
0030:
0031:
0032: static CNoise noise;
0033: static int g_iNoiseTex;
0034: static int g_iPilseTrainTex;
0035:
0036:
0037: cgContext *CgContext = NULL;
0038:
0039: static cgProgramIter *VertexProgramIter = NULL;
0040: static cgBindIter *WPMatrix = NULL;
0041: static cgBindIter *WMatrix = NULL;
0042: static cgBindIter *WITMatrix = NULL;
0043: static cgBindIter *LightPos = NULL;
0044: static cgBindIter *ShaderMatrix = NULL;
0045:
0046: static cgProgramIter *FragmentProgramIter = NULL;
0047: static cgBindIter *fLightWoodColorBind = NULL;
0048: static cgBindIter *fDarkWoodColorBind = NULL;
0049: static cgBindIter *fHighNoiseLevelBind = NULL;
0050: static cgBindIter *fBaseRadiusFreqBind = NULL;
0051: static cgBindIter *fLowPulseAmpBind = NULL;
0052: static cgBindIter *NoiseMapBind = NULL;
0053: static cgBindIter *PulseTrainMapBind = NULL;
0054:
0055: void myRotationMatrix(const float fDegree, const float fX, const float fY, const float fZ, float* m_fData)
0056: {
0057: float sinA, cosA;
0058: float invCosA;
0059: float x, y, z;
0060: float xy, xz, yz;
0061: float xx, yy, zz;
0062: float fRadian = fDegree * 0.0174532925199f;
0063:
0064: x = fX;
0065: y = fY;
0066: z = fZ;
0067:
0068: float mult = 1.0f / sqrtf(x * x + y * y + z * z);
0069: x *= mult;
0070: y *= mult;
0071: z *= mult;
0072:
0073:
0074: sinA = (float)sinf(fRadian);
0075: cosA = (float)cosf(fRadian);
0076: invCosA = 1.0f - cosA;
0077:
0078: xy = x * y;
0079: xz = x * z;
0080: yz = y * z;
0081:
0082: xx = x * x;
0083: yy = y * y;
0084: zz = z * z;
0085:
0086: m_fData[0 ] = (invCosA * xx) + (cosA);
0087: m_fData[1 ] = (invCosA * xy) - (sinA * z );
0088: m_fData[2 ] = (invCosA * xz) + (sinA * y );
0089: m_fData[3 ] = 0.0F;
0090:
0091: m_fData[4 ] = (invCosA * xy) + (sinA * z);
0092: m_fData[5 ] = (invCosA * yy) + (cosA);
0093: m_fData[6 ] = (invCosA * yz) - (sinA * x);
0094: m_fData[7 ] = 0.0F;
0095:
0096: m_fData[8 ] = (invCosA * xz) - (sinA * y);
0097: m_fData[9 ] = (invCosA * yz) + (sinA * x);
0098: m_fData[10] = (invCosA * zz) + (cosA);
0099: m_fData[11] = 0.0F;
0100:
0101: m_fData[12] = m_fData[13] = m_fData[14] = 0.0F;
0102:
0103: m_fData[15] = 1.0F;
0104: }
0105:
0106:
0107:
0108:
0109: float getSmoothStep(float min, float max, float x)
0110: {
0111: if (x < min) {
0112: return 0;
0113: }else if (x > max) {
0114: return 1;
0115: }else{
0116: float t = (x-min)/(max-min);
0117: return (3 - 2*t)*t*t;
0118: }
0119: }
0120:
0121:
0122:
0123: GLint generateSmoothPulseTrain()
0124: {
0125: const int iWidth = 512;
0126: unsigned char* pCharBuf = new unsigned char[iWidth];
0127:
0128: for (int i = 0; i < iWidth; ++i) {
0129: float fX = float(i) / float(iWidth);
0130: float fVal = getSmoothStep(0.1, 0.65, fX) - getSmoothStep(0.8, 0.95, fX);
0131: pCharBuf[i] = 255 * fVal;
0132: }
0133:
0134: GLuint texid;
0135: glGenTextures(1, &texid);
0136: glBindTexture(GL_TEXTURE_1D, texid);
0137: glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
0138: glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
0139: glTexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
0140: glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
0141: glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, iWidth, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pCharBuf);
0142:
0143: delete [] pCharBuf;
0144: return texid;
0145: }
0146:
0147:
0148:
0149: void updateLights()
0150: {
0151: ifVector4 v = {-5.0f, 5.0f, 3.0f, 1.0f};
0152: ifMatrix m;
0153:
0154:
0155: glGetFloatv(GL_TRANSPOSE_MODELVIEW_MATRIX_ARB, (float*)&m[0][0]);
0156:
0157:
0158: ifMatrixTranspose(&m, (const ifMatrix *)&m);
0159: ifVec4Transform(&v, &v, (const ifMatrix *)&m);
0160:
0161: cgGLBindUniform4f(VertexProgramIter, LightPos, v[0], v[1], v[2], v[3]);
0162: }
0163:
0164:
0165:
0166: void display(void)
0167: {
0168: ifMatrix mWorld, m;
0169: cgError Ret;
0170:
0171:
0172:
0173:
0174: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
0175:
0176:
0177:
0178:
0179: glMatrixMode(GL_MODELVIEW);
0180: glLoadIdentity();
0181: gluLookAt( 0.0, 4.0, 6.0,
0182: 0.0, 1.0, 0.0,
0183: 0.0, 1.0, 0.0);
0184:
0185: glPushMatrix();
0186:
0187:
0188:
0189:
0190: updateLights();
0191:
0192:
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:
0205:
0206: cgGLActiveTexture(NoiseMapBind);
0207: glEnable(GL_TEXTURE_3D_EXT);
0208: glBindTexture(GL_TEXTURE_3D_EXT, g_iNoiseTex);
0209:
0210: cgGLActiveTexture(PulseTrainMapBind);
0211: glEnable(GL_TEXTURE_1D);
0212: glBindTexture(GL_TEXTURE_1D, g_iPilseTrainTex);
0213:
0214:
0215:
0216:
0217: ifMatrixIdentity( &mWorld );
0218: ifMatrixRotationX(&m, -IF_PI*90/180);
0219: ifMatrixMultiply( &mWorld, (const ifMatrix *)&mWorld, (const ifMatrix *)&m );
0220: ifMatrixRotationY(&m, IF_PI* r/180);
0221: ifMatrixMultiply( &mWorld, (const ifMatrix *)&mWorld, (const ifMatrix *)&m );
0222:
0223: glMultMatrixf((const float *)&mWorld);
0224:
0225: #if 0
0226:
0227: cgGLBindUniform4f(FragmentProgramIter, fLightWoodColorBind, 0.76, 0.41, 0.17, 0.0);
0228: cgGLBindUniform4f(FragmentProgramIter, fDarkWoodColorBind, 0.42, 0.22, 0.03, 0.0);
0229: cgGLBindUniform4f(FragmentProgramIter, fHighNoiseLevelBind, 0.04, 0.0, 0.0, 0.0);
0230: cgGLBindUniform4f(FragmentProgramIter, fBaseRadiusFreqBind, 0.70, 0.0, 0.0, 0.0);
0231: cgGLBindUniform4f(FragmentProgramIter, fLowPulseAmpBind, 1.5, 0.0, 0.0, 0.0);
0232: cgGLBindUniformMatrixcf(VertexProgramIter, ShaderMatrix, (const float *)&mWorld[0][0]);
0233: #else
0234:
0235: cgGLBindUniform4f(FragmentProgramIter, fLightWoodColorBind, 0.76, 0.54, 0.32, 0.0);
0236: cgGLBindUniform4f(FragmentProgramIter, fDarkWoodColorBind, 0.62, 0.38, 0.20, 0.0);
0237: cgGLBindUniform4f(FragmentProgramIter, fBaseRadiusFreqBind, 1.10, 0.0, 0.0, 0.0);
0238: cgGLBindUniform4f(FragmentProgramIter, fHighNoiseLevelBind, 0.03, 0.0, 0.0, 0.0);
0239: cgGLBindUniform4f(FragmentProgramIter, fLowPulseAmpBind, 1.0, 0.0, 0.0, 0.0);
0240:
0241: ifMatrix m0, m1;
0242: ifMatrixScaling( &m0, 10, 10, 10 );
0243: myRotationMatrix(20, 1.0f, 1.0f, 0.0f , (float*)&m1[0][0]);
0244: ifMatrixMultiply(&m0, (const ifMatrix *)&m0, (const ifMatrix *)&m1);
0245: ifMatrixTranspose(&m0, (const ifMatrix *)&m0);
0246: cgGLBindUniformMatrixcf(VertexProgramIter, ShaderMatrix, (const float *)&m0[0][0]);
0247: #endif
0248:
0249:
0250: cgGLBindUniformStateMatrix(VertexProgramIter, WPMatrix,
0251: cgGLModelViewProjectionMatrix, cgGLMatrixIdentity);
0252:
0253: cgGLBindUniformStateMatrix(VertexProgramIter, WMatrix,
0254: cgGLModelViewMatrix, cgGLMatrixIdentity);
0255:
0256: cgGLBindUniformStateMatrix(VertexProgramIter, WITMatrix,
0257: cgGLModelViewMatrix, cgGLMatrixTranspose | cgGLMatrixInverse);
0258:
0259:
0260:
0261:
0262: glutSolidTeapot(1);
0263:
0264:
0265:
0266:
0267:
0268: cgGLActiveTexture(NoiseMapBind); glDisable(GL_TEXTURE_3D_EXT);
0269: cgGLActiveTexture(PulseTrainMapBind); glDisable(GL_TEXTURE_1D);
0270:
0271: cgGLDisableProgramType(cgFragmentProfile);
0272: cgGLDisableProgramType(cgVertexProfile);
0273:
0274: glPopMatrix();
0275: glutSwapBuffers();
0276: }
0277:
0278:
0279:
0280: void resize(int w, int h)
0281: {
0282:
0283: glViewport(0, 0, w, h);
0284:
0285:
0286: glMatrixMode(GL_PROJECTION);
0287: glLoadIdentity();
0288: gluPerspective( 60.0,
0289: 1.0,
0290: 0.1, 10.0);
0291: }
0292:
0293:
0294:
0295: void idle()
0296: {
0297:
0298: r = r + 3.0f;
0299: while (360.0f < r) r -= 360.0f;
0300:
0301:
0302: glutPostRedisplay();
0303: }
0304:
0305:
0306:
0307: static void InitializeGlut(int argc, char *argv[])
0308: {
0309:
0310: glutInit(&argc, argv);
0311: glutInitDisplayMode(GLUT_DOUBLE
0312: | GLUT_RGBA
0313: | GLUT_DEPTH);
0314: glutInitWindowPosition(100, 100);
0315: glutInitWindowSize(512, 512);
0316: glutCreateWindow("Wood");
0317:
0318:
0319: glutDisplayFunc(display);
0320: glutReshapeFunc(resize);
0321: glutIdleFunc(idle);
0322:
0323:
0324: glClearColor(0.23, 0.43, 0.64, 0.0);
0325: glEnable(GL_DEPTH_TEST);
0326: }
0327:
0328:
0329:
0330: static void InitializeCg()
0331: {
0332: cgError Ret;
0333:
0334:
0335: CgContext = cgCreateContext();
0336: assert(CgContext != NULL);
0337:
0338:
0339: Ret = cgAddProgramFromFile(CgContext, "vp.cg", cgVertexProfile, NULL);
0340: fprintf(stderr, "LAST LISTING----%s----\n", cgGetLastListing(CgContext));
0341: assert(Ret == cgNoError);
0342:
0343:
0344: VertexProgramIter = cgProgramByName(CgContext, "main");
0345: assert(VertexProgramIter != NULL);
0346:
0347: #if 0
0348:
0349: fprintf(stderr, "---- プログラム はじめ ----\n"
0350: "%s"
0351: "---- プログラム 終わり ----\n",
0352: cgGetProgramObjectCode(VertexProgramIter));
0353: #endif
0354:
0355: if(VertexProgramIter != NULL) {
0356: GLuint ProgId = 1;
0357:
0358: Ret = cgGLLoadProgram(VertexProgramIter, ProgId);
0359: assert(Ret == cgNoError);
0360:
0361: LightPos = cgGetBindByName(VertexProgramIter, "LightPosition");
0362: WPMatrix = cgGetBindByName(VertexProgramIter, "ModelViewProj");
0363: WMatrix = cgGetBindByName(VertexProgramIter, "ModelView");
0364: WITMatrix = cgGetBindByName(VertexProgramIter, "ModelViewIT");
0365: ShaderMatrix= cgGetBindByName(VertexProgramIter, "ShaderMatrix");
0366:
0367:
0368: assert(LightPos != NULL);
0369: assert(WPMatrix != NULL);
0370: assert(WMatrix != NULL);
0371: assert(WITMatrix != NULL);
0372: assert(ShaderMatrix != NULL);
0373: }
0374:
0375:
0376:
0377: Ret = cgAddProgramFromFile(CgContext, "fp.cg", cgFragmentProfile, NULL);
0378: assert(Ret == cgNoError);
0379:
0380:
0381: FragmentProgramIter = cgProgramByName(CgContext, "main");
0382: assert(FragmentProgramIter != NULL);
0383:
0384: #if 0
0385:
0386: fprintf(stderr, "---- プログラム はじめ ----\n"
0387: "%s"
0388: "---- プログラム 終わり ----\n",
0389: cgGetProgramObjectCode(FragmentProgramIter));
0390: #endif
0391: if(FragmentProgramIter != NULL) {
0392: GLuint ProgId = 2;
0393:
0394: Ret = cgGLLoadProgram(FragmentProgramIter, ProgId);
0395: assert(Ret == cgNoError);
0396:
0397: fLightWoodColorBind = cgGetBindByName(FragmentProgramIter, "fLightWood");
0398: fDarkWoodColorBind = cgGetBindByName(FragmentProgramIter, "fDarkWood");
0399: fHighNoiseLevelBind = cgGetBindByName(FragmentProgramIter, "fHighNoiseLevel");
0400: fBaseRadiusFreqBind = cgGetBindByName(FragmentProgramIter, "fBaseRadiusFreq");
0401: fLowPulseAmpBind = cgGetBindByName(FragmentProgramIter, "fLowPulseAmp");
0402: NoiseMapBind = cgGetBindByName(FragmentProgramIter, "NoiseMap");
0403: PulseTrainMapBind = cgGetBindByName(FragmentProgramIter, "PulseTrainMap");
0404:
0405:
0406: assert(fLightWoodColorBind != NULL);
0407: assert(fDarkWoodColorBind != NULL);
0408: assert(fHighNoiseLevelBind != NULL);
0409: assert(fBaseRadiusFreqBind != NULL);
0410: assert(fLowPulseAmpBind != NULL);
0411: assert(NoiseMapBind != NULL);
0412: assert(PulseTrainMapBind != NULL);
0413: }
0414:
0415: }
0416:
0417:
0418:
0419: static void CleanupCg()
0420: {
0421:
0422: if(PulseTrainMapBind )cgFreeBindIter( PulseTrainMapBind );
0423: if(NoiseMapBind )cgFreeBindIter( NoiseMapBind );
0424: if(fLowPulseAmpBind )cgFreeBindIter( fLowPulseAmpBind );
0425: if(fBaseRadiusFreqBind )cgFreeBindIter( fBaseRadiusFreqBind );
0426: if(fHighNoiseLevelBind )cgFreeBindIter( fHighNoiseLevelBind );
0427: if(fDarkWoodColorBind )cgFreeBindIter( fDarkWoodColorBind );
0428: if(fLightWoodColorBind )cgFreeBindIter( fLightWoodColorBind );
0429: cgFreeProgramIter( FragmentProgramIter );
0430:
0431:
0432: if(LightPos )cgFreeBindIter( LightPos );
0433: if(WPMatrix )cgFreeBindIter( WPMatrix );
0434: if(WMatrix )cgFreeBindIter( WMatrix );
0435: if(WITMatrix )cgFreeBindIter( WITMatrix );
0436: if(ShaderMatrix )cgFreeBindIter( ShaderMatrix );
0437: cgFreeProgramIter( VertexProgramIter );
0438:
0439: cgFreeContext( CgContext );
0440: cgCleanup( );
0441: }
0442:
0443:
0444:
0445: int main(int argc, char *argv[])
0446: {
0447:
0448: InitializeGlut(argc, argv);
0449: InitializeCg();
0450:
0451: g_iNoiseTex = noise.CreateNoiseTexture3D(64,64,64,1.0,1.0);
0452: g_iPilseTrainTex = generateSmoothPulseTrain();
0453:
0454:
0455: glutMainLoop();
0456:
0457:
0458: CleanupCg();
0459:
0460: return 0;
0461: }