// This code example is created for educational purpose // by Thorsten Thormaehlen (contact: www.thormae.de). // It is distributed without any warranty. #include // we use glut here as window manager #include #ifndef M_PI #define M_PI 3.1415926535897932385f #endif #include #include #include #include using namespace std; class Renderer { public: Renderer() : rot1(0.0), rot2(0.0), rot3(0.0) {} public: void display() { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // view scene from the side glTranslatef(0.0f,0.0f,-3.0f); glRotatef( -45.0f, 0.0f, 0.0f, 1.0f); glRotatef( -45.0f, 0.0f, 1.0f, 0.0f); glRotatef( 135.0f, 1.0f, 0.0f, 0.0f); // rotate around z glRotatef(rot1, 0.0f, 0.0f, 1.0f); glColor3f(0.0f, 0.0f, 1.0f); drawCoordinateAxisZ(); // rotate around local y glRotatef(rot2, 0.0f, 1.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); drawCoordinateAxisY(); // rotate around local x glRotatef(rot3, 1.0f, 0.0f, 0.0f); glColor3f(1.0f, 0.0f, 0.0f); drawCoordinateAxisX(); // draw the plane in the local coordinate system drawToyPlane(); } void init() { // read vertex data from file std::ifstream input("ToyPlaneData.txt"); if(!input) { cout << "Can not find vertex data file \"ToyPlaneData.txt\"" << endl; } else { int vertSize; double vertData; if(input >> vertSize) { if(vertSize > 0) { toyPlaneData.resize(vertSize); int i = 0; while(input >> vertData && i < vertSize) { // store it in the vector. toyPlaneData[i] = vertData; i++; } if(i != vertSize || vertSize % 3) toyPlaneData.resize(0); } } input.close(); } // set opengl states glEnable(GL_DEPTH_TEST); } void resize(int w, int h) { // ignore this for now glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective (45.0, (float)w/(float)h, 0.1, 10.0); } void dispose() { } public: float rot1; float rot2; float rot3; std::vector toyPlaneData; private: void drawCoordinateAxisZ() { glBegin(GL_LINE_LOOP); // circle in x-y plane for(int a=0; a<360; a+=10) { float angle = M_PI / 180.0f * a; glVertex3f(cos(angle), sin(angle), 0.0); } glEnd(); glBegin(GL_LINES); glVertex3f(0.9f, 0.0f, 0.0f); // x-axis glVertex3f(1.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.9f, 0.0f); // y-axis glVertex3f(0.0f, 1.0f, 0.0f); glVertex3f(0.0f, 0.0f,-1.0f); // z-axis glVertex3f(0.0f, 0.0f, 1.0f); glEnd(); glBegin(GL_TRIANGLES); // z-axis tip glVertex3f(0.0f,-0.1f, 0.9f); glVertex3f(0.0f, 0.0f, 1.0f); glVertex3f(0.0f, 0.1f, 0.9f); glEnd(); } void drawCoordinateAxisX() { glPushMatrix(); glRotatef(90.0f, 0.0f, 1.0f, 0.0f); drawCoordinateAxisZ(); glPopMatrix(); } void drawCoordinateAxisY() { glPushMatrix(); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); drawCoordinateAxisZ(); glPopMatrix(); } void drawToyPlane() { glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLES); for(unsigned i=0; i < toyPlaneData.size(); i+=3) { glVertex3d(toyPlaneData[i],toyPlaneData[i+1], toyPlaneData[i+2]); } glEnd(); } }; //this is a static pointer to a Renderer used in the glut callback functions static Renderer *renderer; //glut static callbacks start static void glutResize(int w, int h) { renderer->resize(w,h); } static void glutDisplay() { renderer->display(); glutSwapBuffers(); } static void glutKeyboard(unsigned char key, int x, int y) { bool redraw = false; float offset = 2.5f; if (glutGetModifiers() & GLUT_ACTIVE_ALT) { offset = -offset; } switch(key) { case '1': renderer->rot1 += offset; redraw = true; break; case '2': renderer->rot2 += offset; redraw = true; break; case '3': renderer->rot3 += offset; redraw = true; break; case '0': renderer->rot1 = 0.0f; renderer->rot2 = 0.0f; renderer->rot3 = 0.0f; redraw = true; break; } if(redraw) { std::stringstream ss; ss << "Yaw " << renderer->rot1 <<", Pitch " << renderer->rot2 << ", Roll " << renderer->rot3; glutSetWindowTitle(ss.str().c_str()); glutDisplay(); } } static void glutClose() { renderer->dispose(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100,100); glutInitWindowSize(320, 320); glutCreateWindow("Use 1, 2, and 3 keys to rotate (ALT+key rotates in other direction)"); glutDisplayFunc(glutDisplay); //glutIdleFunc(glutDisplay); glutReshapeFunc(glutResize); glutKeyboardFunc(glutKeyboard); glutCloseFunc(glutClose); renderer = new Renderer; renderer->init(); glutMainLoop(); }