// // knot // // Created by Bill on 08/07/2007. // #include #include #include #include #include #include #include "vectors.h" #define kWindowWidth 800 #define kWindowHeight 600 int nx, ny, numNormals; GLvec** mesh; GLvec* normals; GLfloat r, ang, dang, rot; GLfloat pi = 3.1415926535f; GLfloat lightAmbient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; GLfloat lightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat lightSpecular[] = { 0.2f, 0.2f, 0.2f, 1.0f }; GLfloat lightPosition[] = { 50.0f, -40.0f, -20.0f, 1.0f }; GLfloat materialAmbient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; GLfloat materialDiffuse[] = { 0.5f, 0.6f, 1.0f, 1.0f }; GLfloat materialSpecular[] = { 0.1f, 0.1f, 0.1f, 1.0f }; GLvoid InitGL(GLvoid); GLvoid DrawGLScene(GLvoid); GLvoid ReSizeGLScene(int Width, int Height); void initSurface(); int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (kWindowWidth, kWindowHeight); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); InitGL(); initSurface(); glutDisplayFunc(DrawGLScene); glutReshapeFunc(ReSizeGLScene); glutMainLoop(); delete [] mesh; delete [] normals; return 0; } GLvec knotCoord(GLfloat a) { GLvec coord; coord.x = sin(a) + 2*sin(2*a); coord.y = 1.25*sin(3*a); coord.z = cos(a) - 2*cos(2*a); return coord; } void initSurface() { nx = 40; ny = 200; r = 0.6f; // declare vertices array mesh = new GLvec*[nx]; for (int i = 0; i < nx; i++) mesh[i] = new GLvec[ny]; // fill arrays // mesh GLvec y_axis(0.0f, 1.0f, 0.0f); GLvec lastpos, curpos, nextpos, axis, orth1, orth2; GLfloat cang, dcang; ang = 0; dang = 2*pi/(ny-1); dcang = 2*pi/(nx-1); for (int j = 0; j < ny; j++) { lastpos = knotCoord(ang-dang); curpos = knotCoord(ang); nextpos = knotCoord(ang+dang); axis = nextpos - lastpos; orth1 = normalize(cross(axis, y_axis)); orth2 = normalize(cross(axis, orth1)); cang = 0; for (int i = 0; i < nx; i++) { mesh[i][j] = curpos + orth1*(r*sin(cang)) + orth2*(r*cos(cang)); cang += dcang; } ang += dang; } // declare normals array numNormals = (nx-1)*(ny-1)*2; normals = new GLvec[numNormals]; // calculate normals GLvec e1, e2; int ni = 0; for (int j = 0; j < (ny-1); j++) for (int i = 0; i < (nx-1); i++) { e1 = mesh[i+1][j] - mesh[i][j]; e2 = mesh[i+1][j+1] - mesh[i][j]; normals[ni] = normalize(cross(e1, e2)); e1 = mesh[i+1][j+1] - mesh[i][j]; e2 = mesh[i][j+1] - mesh[i][j]; normals[ni+1] = normalize(cross(e1, e2)); ni += 2; } rot = 0; } void calculateSurface() { } GLvoid InitGL(GLvoid) { glClearColor(0.1f, 0.2f, 0.5f, 0.0f); glClearDepth(1.0); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glShadeModel(GL_SMOOTH); glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmbient); glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDiffuse); glLightfv(GL_LIGHT1, GL_SPECULAR, lightSpecular); glLightfv(GL_LIGHT1, GL_POSITION, lightPosition); glEnable(GL_LIGHT1); glEnable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f,(GLfloat)kWindowWidth/(GLfloat)kWindowHeight,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); } GLvoid DrawGLScene(GLvoid) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -10.0f); glRotatef(30.0f, 1.0f, 0.0f, 0.0f); glRotatef(rot, 0.0f, 1.0f, 0.0f); glRotatef(rot/3, 0.0f, 0.0f, 1.0f); glBegin(GL_TRIANGLES); glColor3f(1.0f, 1.0f, 1.0f); glMaterialfv(GL_FRONT, GL_AMBIENT, materialAmbient); glMaterialfv(GL_FRONT, GL_DIFFUSE, materialDiffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, materialSpecular); int ni = 0; for (int j = 0; j < (ny-1); j++) for (int i = 0; i < (nx-1); i++) { glNormal3f(normals[ni].x, normals[ni].y, normals[ni].z); glVertex3f(mesh[i][j].x, mesh[i][j].y, mesh[i][j].z); glVertex3f(mesh[i+1][j].x, mesh[i+1][j].y, mesh[i+1][j].z); glVertex3f(mesh[i+1][j+1].x, mesh[i+1][j+1].y, mesh[i+1][j+1].z); glNormal3f(normals[ni+1].x, normals[ni+1].y, normals[ni+1].z); glVertex3f(mesh[i][j].x, mesh[i][j].y, mesh[i][j].z); glVertex3f(mesh[i+1][j+1].x, mesh[i+1][j+1].y, mesh[i+1][j+1].z); glVertex3f(mesh[i][j+1].x, mesh[i][j+1].y, mesh[i][j+1].z); ni += 2; } rot += 0.25; glEnd(); glFlush(); glutSwapBuffers(); glutPostRedisplay(); } GLvoid ReSizeGLScene(int Width, int Height) { glViewport (0, 0, (GLsizei) Width, (GLsizei) Height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (GLfloat) Width / (GLfloat) Height, 0.1, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); }