// 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 using namespace std; class Renderer { public: Renderer() : t(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); if(true) { // interpolate rotation matrices, which is wrong float r0[16]; float r1[16]; float rt[16]; glPushMatrix(); // save for later use glLoadIdentity(); glGetFloatv(GL_MODELVIEW_MATRIX, r0); // rotate around z glRotatef(180.0f, 0.0f, 0.0f, 1.0f); glGetFloatv(GL_MODELVIEW_MATRIX, r1); glPopMatrix(); // restore //interpolate for(unsigned i=0; i < 16; i++) { rt[i] = (1-t) * r0[i] + t * r1[i]; } glMultMatrixf(rt); }else{ // interpolate rotation angle, which is correct // rotate around z glRotatef(t*180.0f, 0.0f, 0.0f, 1.0f); } glColor3f(0.0f, 0.0f, 1.0f); drawCoordinateAxisZ(); glColor3f(0.0f, 1.0f, 0.0f); drawCoordinateAxisY(); glColor3f(1.0f, 0.0f, 0.0f); drawCoordinateAxisX(); } void init() { 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 t; //time 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(); } }; //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 = 0.02f; if (glutGetModifiers() & GLUT_ACTIVE_ALT) { offset = -offset; } switch(key) { case '1': renderer->t += offset; if(renderer->t < 0.0f) renderer->t = 1.0; if(renderer->t > 1.0f) renderer->t = 0.0; redraw = true; break; } if(redraw) { std::stringstream ss; ss << "Time " << renderer->t; glutSetWindowTitle(ss.str().c_str()); glutDisplay(); } } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100,100); glutInitWindowSize(320, 320); glutCreateWindow("Use the 1 key to interpolate rotation"); glutDisplayFunc(glutDisplay); //glutIdleFunc(glutDisplay); glutReshapeFunc(glutResize); glutKeyboardFunc(glutKeyboard); renderer = new Renderer; renderer->init(); glutMainLoop(); }