#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <GL/glut.h>
#include <GL/gl.h>

float viewRotY = 0, viewRotX = 0;


void drawCoordinateAxes(void)
	{
	glLineWidth(2.0);
	glColor3f(1.0, 1.0, 0.0);
	glBegin(GL_LINES);
	 glVertex3f(-1.0, 0.0, 0.0);
	 glVertex3f(1.0, 0.0, 0.0);
	 glVertex3f(0.0, -1.0, 0.0);
	 glVertex3f(0.0, 1.0, 0.0);
	 glVertex3f(0.0, 0.0, -1.0);
	 glVertex3f(0.0, 0.0, 1.0);
	glEnd();
	glLineWidth(1.0);
	glColor3f(1.0, 0.0, 0.0);
	glRasterPos3f(1.0, 0.0, 0.0);
	glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'X');
	glRasterPos3f(0.0, 1.0, 0.0);
	glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'Y');
	glRasterPos3f(0.0, 0.0, 1.0);
	glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'Z');
	}



void drawEverything(void)
	{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(50.0, 1.0, 1.0, 100.0);
	glMatrixMode(GL_MODELVIEW);

	glLoadIdentity();
	glTranslatef(0.0, 0.0, -8.0);
	glRotatef(viewRotX, 1.0, 0.0, 0.0);
	glRotatef(viewRotY, 0.0, 1.0, 0.0);
	
	glPushMatrix();
	
	  drawCoordinateAxes();

	  glTranslatef(2.0, 2.0, 1.0);
	  glRotatef(40.0, 1.0, 0.0, 0.0);
	
	  drawCoordinateAxes();
	  glColor3f(0.0, 1.0, 1.0);
	  glutWireTorus(0.2, 1.0, 6, 12);

	  glPushMatrix();
	    glTranslatef(-3.0, 0.0, 0.0);
	    glColor3f(1.0, 1.0, 0.0);
	    glutWireTorus(0.2, 1.0, 6, 12);
	  glPopMatrix();
	
	  glPushMatrix();
	    glTranslatef(0.0, 0.0, 2.0);
	    glScalef(0.25, 0.5, 0.5);
	    glColor3f(1.0, 0.0, 1.0);
	    glutWireTorus(0.2, 1.0, 6, 12);
	  glPopMatrix();
	
	glPopMatrix();
	
	glutSwapBuffers();
	}


static void key(unsigned char k, int x, int y)
	{
	if (k == 27)
		exit(0);
	glutPostRedisplay();
	}


static void specialkey(int k, int x, int y)
	{
	if (k == GLUT_KEY_LEFT)
		viewRotY += 3;
	else if (k == GLUT_KEY_RIGHT)
		viewRotY -= 3;
	else if (k == GLUT_KEY_UP)
		viewRotX += 3;
	else if (k == GLUT_KEY_DOWN)
		viewRotX -= 3;
	glutPostRedisplay();
	}



int main(int argc, char *argv[])
	{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
	glutCreateWindow("example");
	glutDisplayFunc(drawEverything);
	glutKeyboardFunc(key);
	glutSpecialFunc(specialkey);
	glutMainLoop();
	return 0;
	}
