#include #include #include using namespace std; #include #include #include #include #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif //============================================================================== class Vertex { //============================================================================== public: double x, y, z; Vertex( double x=0, double y=0, double z=0 ) { setCoordinates( x, y, z ); } void setCoordinates( double xval, double yval, double zval ) { x = xval; y = yval; z = zval; } }; //============================================================================== class Triangle //============================================================================== { public: int v0, v1, v2; Triangle( int v0=-1, int v1=-1, int v2=-1 ) : v0(v0), v1(v1), v2(v2) {} }; //============================================================================== class Lamp //============================================================================== { public: enum { HEAD = 0, NECK = 1, BODY = 2, BASE = 3 }; vector headVert; vector headTri; vector neckVert; vector neckTri; vector bodyVert; vector bodyTri; vector baseVert; vector baseTri; vector nullVert; vector nullTri; Lamp( ) { int i; float x, y; int nFaces; int v, t; // create head nFaces = 16; headVert.resize(3*nFaces+1); headTri.resize(5*nFaces); headVert[0] = Vertex(1.0f, 0.0f, 2.0f); t = 0; v = 1; for (i = 0; i < nFaces; i++) { x = (float) cos(2.0*M_PI*i/nFaces); y = (float) sin(2.0*M_PI*i/nFaces); headVert[v++] = Vertex(x+1.0, y, 2.0f); headVert[v++] = Vertex(x+1.0, y, -1.0f); headVert[v++] = Vertex(3*x+1.0, 3*y, -4.0f); if (i > 0) { headTri[t++] = Triangle(0, 3*i-2, 3*i+1); headTri[t++] = Triangle(3*i-2, 3*i-1, 3*i+1); headTri[t++] = Triangle(3*i-1, 3*i+2, 3*i+1); headTri[t++] = Triangle(3*i-1, 3*i, 3*i+2); headTri[t++] = Triangle(3*i, 3*i+3, 3*i+2); } } i = nFaces; headTri[t++] = Triangle(0, 3*i-2, 1); headTri[t++] = Triangle(3*i-2, 3*i-1, 1); headTri[t++] = Triangle(3*i-1, 2, 1); headTri[t++] = Triangle(3*i-1, 3*i, 2); headTri[t++] = Triangle(3*i, 3, 2); // create neck neckVert.resize(8+8+12); neckTri.resize(12+12+4); v = 0; t = 0; box(v,t, neckVert, neckTri, 1.0f, 11.0f, -0.15f, 0.15f, 0.2f, 0.5f); box(v,t, neckVert, neckTri, 1.0f, 11.0f, -0.15f, 0.15f, -0.5f, -0.2f); neckVert[v++] = Vertex(0.0f, -0.16f, 0.0f); neckVert[v++] = Vertex(1.0f, -0.16f, -0.5f); neckVert[v++] = Vertex(1.0f, -0.16f, 0.5f); neckTri[t++] = Triangle(v-3, v-2, v-1); neckVert[v++] = Vertex(0.0f, 0.16f, 0.0f); neckVert[v++] = Vertex(1.0f, 0.16f, 0.5f); neckVert[v++] = Vertex(1.0f, 0.16f, -0.5f); neckTri[t++] = Triangle(v-3, v-2, v-1); neckVert[v++] = Vertex(12.0f, -0.16f, 0.0f); neckVert[v++] = Vertex(11.0f, -0.16f, 0.5f); neckVert[v++] = Vertex(11.0f, -0.16f, -0.5f); neckTri[t++] = Triangle(v-3, v-2, v-1); neckVert[v++] = Vertex(12.0f, 0.16f, 0.0f); neckVert[v++] = Vertex(11.0f, 0.16f, -0.5f); neckVert[v++] = Vertex(11.0f, 0.16f, 0.5f); neckTri[t++] = Triangle(v-3, v-2, v-1); // create body bodyVert.resize(8+8+12); bodyTri.resize(12+12+4); v = 0; t = 0; box(v,t,bodyVert, bodyTri, 1.0f, 11.0f, -0.15f, 0.15f, 0.2f, 0.5f); box(v,t,bodyVert, bodyTri, 1.0f, 11.0f, -0.15f, 0.15f, -0.5f, -0.2f); bodyVert[v++] = Vertex(0.0f, -0.16f, 0.0f); bodyVert[v++] = Vertex(1.0f, -0.16f, -0.5f); bodyVert[v++] = Vertex(1.0f, -0.16f, 0.5f); bodyTri[t++] = Triangle(v-3, v-2, v-1); bodyVert[v++] = Vertex(0.0f, 0.16f, 0.0f); bodyVert[v++] = Vertex(1.0f, 0.16f, 0.5f); bodyVert[v++] = Vertex(1.0f, 0.16f, -0.5f); bodyTri[t++] = Triangle(v-3, v-2, v-1); bodyVert[v++] = Vertex(12.0f, -0.16f, 0.0f); bodyVert[v++] = Vertex(11.0f, -0.16f, 0.5f); bodyVert[v++] = Vertex(11.0f, -0.16f, -0.5f); bodyTri[t++] = Triangle(v-3, v-2, v-1); bodyVert[v++] = Vertex(12.0f, 0.16f, 0.0f); bodyVert[v++] = Vertex(11.0f, 0.16f, -0.5f); bodyVert[v++] = Vertex(11.0f, 0.16f, 0.5f); bodyTri[t++] = Triangle(v-3, v-2, v-1); //create base baseVert.resize(2*nFaces+2+6); baseTri.resize(4*nFaces+2); int q = 2*nFaces+1; baseVert[0] = Vertex(0.0f, 0.0f, 1.0f); baseVert[q] = Vertex(0.0f, 0.0f, 0.0f); t = 0; v = 1; for (i = 0; i < nFaces; i++) { x = (float) cos(2.0*M_PI*i/nFaces); y = (float) sin(2.0*M_PI*i/nFaces); baseVert[v++] = Vertex(4*x, 4*y, 0.75f); baseVert[v++] = Vertex(4*x, 4*y, 0.0f); if (i > 0) { baseTri[t++] = Triangle(0, 2*i-1, 2*i+1); baseTri[t++] = Triangle(2*i-1, 2*i, 2*i+2); baseTri[t++] = Triangle(2*i-1, 2*i+2, 2*i+1); baseTri[t++] = Triangle(2*i, q, 2*i+2); } } i = nFaces; v++; baseTri[t++] = Triangle(0, 2*i-1, 1); baseTri[t++] = Triangle(2*i-1, 2*i, 2); baseTri[t++] = Triangle(2*i-1, 2, 1); baseTri[t++] = Triangle(2*i, q, 2); baseVert[v++] = Vertex(-1.0f, -0.16f, 0.75f); baseVert[v++] = Vertex(1.0f, -0.16f, 0.75f); baseVert[v++] = Vertex(0.0f, -0.16f, 2.5f); baseTri[t++] = Triangle(v-3, v-2, v-1); baseVert[v++] = Vertex(1.0f, 0.16f, 0.75f); baseVert[v++] = Vertex(-1.0f, 0.16f, 0.75f); baseVert[v++] = Vertex(0.0f, 0.16f, 2.5f); baseTri[t++] = Triangle(v-3, v-2, v-1); } void box(int& v, int& t, vector& vList, vector& tList, float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) { // 8 verts and 12 tris int b = v; vList[v++] = Vertex(xmin, ymin, zmin); vList[v++] = Vertex(xmax, ymin, zmin); vList[v++] = Vertex(xmin, ymax, zmin); vList[v++] = Vertex(xmax, ymax, zmin); vList[v++] = Vertex(xmin, ymin, zmax); vList[v++] = Vertex(xmax, ymin, zmax); vList[v++] = Vertex(xmin, ymax, zmax); vList[v++] = Vertex(xmax, ymax, zmax); tList[t++] = Triangle(b+0, b+2, b+3); tList[t++] = Triangle(b+0, b+3, b+1); tList[t++] = Triangle(b+0, b+6, b+2); tList[t++] = Triangle(b+0, b+4, b+6); tList[t++] = Triangle(b+0, b+1, b+5); tList[t++] = Triangle(b+0, b+5, b+4); tList[t++] = Triangle(b+7, b+3, b+2); tList[t++] = Triangle(b+7, b+2, b+6); tList[t++] = Triangle(b+7, b+5, b+1); tList[t++] = Triangle(b+7, b+1, b+3); tList[t++] = Triangle(b+7, b+6, b+4); tList[t++] = Triangle(b+7, b+4, b+5); } int getElements() { return 4; } vector& getVertices(int element) { if (element == HEAD) return headVert; if (element == NECK) return neckVert; if (element == BODY) return bodyVert; if (element == BASE) return baseVert; return nullVert; } vector getTriangles(int element) { if (element == HEAD) return headTri; if (element == NECK) return neckTri; if (element == BODY) return bodyTri; if (element == BASE) return baseTri; return nullTri; } void Draw(int element) { vector& vert = getVertices(element); vector& tri = getTriangles(element); int v; for (int i = 0; i < (int)tri.size(); i++) { glBegin(GL_POLYGON); v = tri[i].v0; glVertex3d(vert[v].x, vert[v].y, vert[v].z); v = tri[i].v1; glVertex3d(vert[v].x, vert[v].y, vert[v].z); v = tri[i].v2; glVertex3d(vert[v].x, vert[v].y, vert[v].z); glEnd(); } } }; Lamp mom; int width, height; int mode = 0; void Draw() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); if( mode == 0 ) { gluLookAt(0, 0,-60, 0,0,0, 0,1,0); // world-to-camera transform glRotated(-90, 1, 0, 0); glColor3d(0,0,1); mom.Draw(Lamp::BASE); mom.Draw(Lamp::BODY); mom.Draw(Lamp::NECK); mom.Draw(Lamp::HEAD); } else if( mode == 1 ) { glTranslated(0.0, 0.0, -60.0); // world-to-view transform glColor3d(0,0,1); glRotated(-90, 1, 0, 0); // base-to-world transform mom.Draw(Lamp::BASE); glTranslated(0,0,2.5); // body-to-base transform mom.Draw(Lamp::BODY); glTranslated(12,0,0); // neck-to-body transform mom.Draw(Lamp::NECK); glTranslated(12,0,0); // head-to-neck transform mom.Draw(Lamp::HEAD); } else { glTranslated(0.0, -12.0, -60.0); // world-to-view transform glColor3d(0,0,1); glRotated(-90, 1, 0, 0); // base-to-world transform mom.Draw(Lamp::BASE); glTranslated(0,0,2.5); // body-to-base transform glRotated(-30, 0, 1, 0); // rotate body at base pivot mom.Draw(Lamp::BODY); glTranslated(12,0,0); // neck-to-body transform glRotated(-115, 0, 1, 0); // rotate neck at body pivot mom.Draw(Lamp::NECK); glTranslated(12,0,0); // head-to-neck transform glRotated(180, 1, 0, 0); // rotate head at neck pivot mom.Draw(Lamp::HEAD); } glFlush(); glutSwapBuffers(); } void Init(int w, int h ) { width = w; height = h; glViewport(0, 0, w, h); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // BackGround Color glEnable(GL_DEPTH_TEST); // Enables Depth Testing glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix gluPerspective(30.0, ((double) w)/((double) h), 0.1, 100.0); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); // Reset The Modelview Matrix } void onKeyPress(unsigned char key, int x, int y) { if( key == ' ' ) mode++; glutPostRedisplay(); } int main( int argc, char *argv[] ) { int w = 256; int h = 256; // glut initialization functions: glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutInitWindowSize(w,h); glutInitWindowPosition(100,100); glutCreateWindow("Luxo"); Init(w, h); glutDisplayFunc(Draw); glutKeyboardFunc(onKeyPress); glutReshapeFunc(Init); glutMainLoop(); return 0; }