0001:
0002:
0003:
0004:
0005:
0006:
0007:
0008:
0009: #include <math.h>
0010: #include <stdio.h>
0011: #include <assert.h>
0012: #include <GL/glut.h>
0013: #include <Cg/cg.h>
0014: #include <Cg/cgGL.h>
0015: #include "matrix.h"
0016:
0017:
0018:
0019:
0020:
0021:
0022: static cgContext *VertexContext = NULL;
0023: static cgProgramIter *VertexProgramIter = NULL;
0024: static cgBindIter *WorldViewProjBind = NULL;
0025: static cgBindIter *WorldBind = NULL;
0026: static cgBindIter *LightBind = NULL;
0027: static cgBindIter *ColorBind = NULL;
0028:
0029: static cgContext *FragmentContext = NULL;
0030: static cgProgramIter *FragmentProgramIter = NULL;
0031: static cgBindIter *HalfBind = NULL;
0032:
0033: static float r = 0.0f;
0034:
0035:
0036:
0037:
0038:
0039: GLint CubeFaces[6][4] =
0040: {
0041: {0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
0042: {4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3}
0043: };
0044:
0045: GLfloat CubeVertices[8][3];
0046: GLfloat CubeNormals[8][3];
0047:
0048: static void InitializeCube(GLfloat v[8][3])
0049: {
0050: v[0][0] = v[1][0] = v[2][0] = v[3][0] = 1;
0051: v[4][0] = v[5][0] = v[6][0] = v[7][0] = -1;
0052: v[0][1] = v[1][1] = v[4][1] = v[5][1] = 1;
0053: v[2][1] = v[3][1] = v[6][1] = v[7][1] = -1;
0054: v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1;
0055: v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;
0056: }
0057: #define MATRIX_INDEX(i, j) (j + i * 4)
0058:
0059:
0060:
0061:
0062: static void DrawCube(void)
0063: {
0064: int i;
0065:
0066:
0067: for(i = 0; i < 6; i++) {
0068: glBegin(GL_QUADS);
0069:
0070: cgGLBindVarying3f(VertexProgramIter, ColorBind
0071: , 0.5f*CubeVertices[CubeFaces[i][0]][0]+0.5f
0072: , 0.5f*CubeVertices[CubeFaces[i][0]][1]+0.5f
0073: , 0.5f*CubeVertices[CubeFaces[i][0]][2]+0.5f
0074: );
0075: glNormal3fv(&CubeNormals [CubeFaces[i][0]][0]);
0076: glVertex3fv(&CubeVertices[CubeFaces[i][0]][0]);
0077:
0078: cgGLBindVarying3f(VertexProgramIter, ColorBind
0079: , 0.5f*CubeVertices[CubeFaces[i][1]][0]+0.5f
0080: , 0.5f*CubeVertices[CubeFaces[i][1]][1]+0.5f
0081: , 0.5f*CubeVertices[CubeFaces[i][1]][2]+0.5f
0082: );
0083: glNormal3fv(&CubeNormals [CubeFaces[i][1]][0]);
0084: glVertex3fv(&CubeVertices[CubeFaces[i][1]][0]);
0085:
0086: cgGLBindVarying3f(VertexProgramIter, ColorBind
0087: , 0.5f*CubeVertices[CubeFaces[i][2]][0]+0.5f
0088: , 0.5f*CubeVertices[CubeFaces[i][2]][1]+0.5f
0089: , 0.5f*CubeVertices[CubeFaces[i][2]][2]+0.5f
0090: );
0091: glNormal3fv(&CubeNormals [CubeFaces[i][2]][0]);
0092: glVertex3fv(&CubeVertices[CubeFaces[i][2]][0]);
0093:
0094: cgGLBindVarying3f(VertexProgramIter, ColorBind
0095: , 0.5f*CubeVertices[CubeFaces[i][3]][0]+0.5f
0096: , 0.5f*CubeVertices[CubeFaces[i][3]][1]+0.5f
0097: , 0.5f*CubeVertices[CubeFaces[i][3]][2]+0.5f
0098: );
0099: glNormal3fv(&CubeNormals [CubeFaces[i][3]][0]);
0100: glVertex3fv(&CubeVertices[CubeFaces[i][3]][0]);
0101:
0102: glEnd();
0103: }
0104: }
0105:
0106:
0107:
0108: void display(void)
0109: {
0110: ifMatrix m, m0;
0111: cgError Ret;
0112:
0113:
0114:
0115:
0116: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
0117:
0118:
0119:
0120:
0121: glMatrixMode(GL_MODELVIEW);
0122: glLoadIdentity();
0123: gluLookAt( 0.0, 0.0, 5.0,
0124: 0.0, 0.0, 0.0,
0125: 0.0, 1.0, 0.0);
0126:
0127: glPushMatrix();
0128:
0129:
0130:
0131:
0132: Ret = cgGLBindProgram(VertexProgramIter);
0133: assert(Ret == cgNoError);
0134: cgGLEnableProgramType(cgVertexProfile);
0135:
0136: Ret = cgGLBindProgram(FragmentProgramIter);
0137: assert(Ret == cgNoError);
0138: cgGLEnableProgramType(cgFragmentProfile);
0139:
0140:
0141:
0142:
0143: ifMatrixIdentity( &m );
0144: ifMatrixRotationZ(&m0, -IF_PI*20/180);
0145: ifMatrixMultiply( &m, (const ifMatrix *)&m, (const ifMatrix *)&m0 );
0146: ifMatrixRotationX(&m0, IF_PI*60/180);
0147: ifMatrixMultiply( &m, (const ifMatrix *)&m, (const ifMatrix *)&m0 );
0148: ifMatrixRotationY(&m0, IF_PI* r/180);
0149: ifMatrixMultiply( &m, (const ifMatrix *)&m, (const ifMatrix *)&m0 );
0150:
0151: glMultMatrixf((const float *)&m);
0152:
0153:
0154: cgGLBindUniformMatrixcf(VertexProgramIter, WorldBind, (const float *)&m[0][0]);
0155:
0156: if(WorldViewProjBind != NULL) {
0157: cgGLBindUniformStateMatrix(VertexProgramIter,
0158: WorldViewProjBind,
0159: cgGLModelViewProjectionMatrix,
0160: cgGLMatrixIdentity);
0161: }
0162:
0163:
0164:
0165:
0166: ifVector4 dir = {0.3f, 0.3f, 0.1f, 0.0f};
0167: ifVec4Normalize(&dir, &dir);
0168:
0169:
0170: ifVector4 eye = {0,0,1,0};
0171: ifVector4 half;
0172: ifVec4Normalize(&half, ifVec4Add(&half, &dir, &eye));
0173: cgGLBindUniform4f(FragmentProgramIter, HalfBind
0174: ,half[0], half[1], half[2], half[3]);
0175:
0176:
0177: ifMatrixTranspose( &m, (const ifMatrix *)&m );
0178: ifVec4Transform(&dir, &dir, (const ifMatrix *)&m);
0179: cgGLBindUniform4f(VertexProgramIter, LightBind
0180: ,dir[0], dir[1], dir[2], dir[3]);
0181:
0182:
0183:
0184:
0185:
0186: DrawCube();
0187:
0188:
0189:
0190:
0191: cgGLDisableProgramType(cgFragmentProfile);
0192: cgGLDisableProgramType(cgVertexProfile);
0193:
0194: glPopMatrix();
0195: glutSwapBuffers();
0196: }
0197:
0198:
0199:
0200: void resize(int w, int h)
0201: {
0202:
0203: glViewport(0, 0, w, h);
0204:
0205:
0206: glMatrixMode(GL_PROJECTION);
0207: glLoadIdentity();
0208: gluPerspective( 60.0,
0209: 1.0,
0210: 1.0, 10.0);
0211: }
0212:
0213:
0214:
0215: void idle()
0216: {
0217:
0218: r = r + 3.0f;
0219: while (360.0f < r) r -= 360.0f;
0220:
0221: glutPostRedisplay();
0222: }
0223:
0224:
0225:
0226: static void InitializeGlut(int argc, char *argv[])
0227: {
0228:
0229: glutInitWindowPosition(100, 100);
0230: glutInitWindowSize(512, 512);
0231: glutInit(&argc, argv);
0232: glutInitDisplayMode(GLUT_DOUBLE
0233: | GLUT_RGBA
0234: | GLUT_DEPTH);
0235: glutCreateWindow(argv[0]);
0236:
0237:
0238: glutDisplayFunc(display);
0239: glutReshapeFunc(resize);
0240: glutIdleFunc(idle);
0241:
0242:
0243: InitializeCube(CubeVertices);
0244: InitializeCube(CubeNormals);
0245: for(int i=0;i<8;i++){
0246:
0247: CubeNormals[i][0] /= sqrt(3);
0248: CubeNormals[i][1] /= sqrt(3);
0249: CubeNormals[i][2] /= sqrt(3);
0250: }
0251:
0252:
0253: glClearColor(0.0, 0.0, 0.3, 0.0);
0254: glEnable(GL_DEPTH_TEST);
0255: }
0256:
0257:
0258:
0259: static void InitializeCg()
0260: {
0261: cgError Ret;
0262:
0263:
0264: VertexContext = cgCreateContext();
0265: assert(VertexContext != NULL);
0266:
0267:
0268: Ret = cgAddProgramFromFile(VertexContext, "vs.cg", cgVertexProfile, NULL);
0269: fprintf(stderr, "LAST LISTING----%s----\n", cgGetLastListing(VertexContext));
0270: assert(Ret == cgNoError);
0271:
0272:
0273: VertexProgramIter = cgProgramByName(VertexContext, "main");
0274: assert(VertexProgramIter != NULL);
0275:
0276:
0277: fprintf(stderr, "---- プログラム はじめ ----\n"
0278: "%s"
0279: "---- プログラム 終わり ----\n",
0280: cgGetProgramObjectCode(VertexProgramIter));
0281:
0282: if(VertexProgramIter != NULL) {
0283: GLuint ProgId = 1;
0284:
0285: Ret = cgGLLoadProgram(VertexProgramIter, ProgId);
0286: assert(Ret == cgNoError);
0287:
0288: WorldViewProjBind = cgGetBindByName(VertexProgramIter, "WorldViewProj");
0289: assert(WorldViewProjBind != NULL);
0290:
0291: WorldBind = cgGetBindByName(VertexProgramIter, "World");
0292: assert(WorldBind != NULL);
0293:
0294: LightBind = cgGetBindByName(VertexProgramIter, "Light");
0295: assert(LightBind != NULL);
0296:
0297: ColorBind = cgGetBindByName(VertexProgramIter, "IN.color");
0298: assert(ColorBind != NULL);
0299: }
0300:
0301:
0302:
0303: FragmentContext = cgCreateContext();
0304: assert(FragmentContext != NULL);
0305:
0306: Ret = cgAddProgramFromFile(FragmentContext, "ps.cg", cgFragmentProfile, NULL);
0307: assert(Ret == cgNoError);
0308:
0309:
0310: FragmentProgramIter = cgProgramByName(FragmentContext, "main");
0311: assert(FragmentProgramIter != NULL);
0312:
0313:
0314: fprintf(stderr, "---- プログラム はじめ ----\n"
0315: "%s"
0316: "---- プログラム 終わり ----\n",
0317: cgGetProgramObjectCode(FragmentProgramIter));
0318:
0319: if(FragmentProgramIter != NULL)
0320: {
0321: GLuint ProgId = 2;
0322:
0323: Ret = cgGLLoadProgram(FragmentProgramIter, ProgId);
0324: assert(Ret == cgNoError);
0325:
0326:
0327: HalfBind = cgGetBindByName(FragmentProgramIter, "Half");
0328: assert(HalfBind != NULL);
0329: }
0330:
0331: }
0332:
0333:
0334:
0335: static void CleanupCg()
0336: {
0337:
0338: if(HalfBind)cgFreeBindIter( HalfBind );
0339: cgFreeProgramIter( FragmentProgramIter );
0340: cgFreeContext( FragmentContext );
0341:
0342:
0343: if(LightBind )cgFreeBindIter( LightBind );
0344: if(WorldBind )cgFreeBindIter( WorldBind );
0345: if(WorldViewProjBind)cgFreeBindIter( WorldViewProjBind );
0346: if(ColorBind )cgFreeBindIter( ColorBind );
0347: cgFreeProgramIter( VertexProgramIter );
0348: cgFreeContext( VertexContext );
0349: cgCleanup( );
0350: }
0351:
0352:
0353:
0354: int main(int argc, char *argv[])
0355: {
0356: InitializeGlut(argc, argv);
0357: InitializeCg();
0358:
0359: glutMainLoop();
0360:
0361: CleanupCg();
0362:
0363: return 0;
0364: }