/******************************************************************************** * Filename: first3d.c * Author : eh * Date: : * * Description: * *******************************************************************************/ //------------------------------------------------------------------------------ // Includes //------------------------------------------------------------------------------ #include #include #include #include //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ #define WIDTH 640 #define HEIGHT 400 #ifndef M_PI #define M_PI 3.14159265358979323846 #endif const GLfloat SELF_ROT = 2.0; const GLfloat SUN_R = 1.0; const GLfloat EARTH_R = 0.3; const GLfloat EARTH_V = 1.0; const GLfloat EARTH_D = 3.0; const GLfloat MOON_R = 0.1; const GLfloat MOON_D = 0.5; const GLfloat NEAR_PLANE = 1.0; const GLfloat FAR_PLANE = 20.0; const GLfloat VIEW_ANGLE = 60.0; const GLfloat FOVY_STEP = 0.5; //------------------------------------------------------------------------------ // Global variables //------------------------------------------------------------------------------ GLfloat gSelfRot = 0.0; GLfloat gEarthAngle = 0.0; GLfloat gMoonAngle = 0.0; GLfloat gViewAngle = 0.0; GLint gPerspective = 0; //------------------------------------------------------------------------------ // Prototypes (not for all functions) //------------------------------------------------------------------------------ void reshape(int w, int h); void drawSpheres(void); void drawCube(void); void renderString(GLfloat x, GLfloat y, char* string); //****************************************************************************** // GLUT "event handlers" //****************************************************************************** //------------------------------------------------------------------------------ // The idle function //------------------------------------------------------------------------------ void idle(void) { gEarthAngle += EARTH_V; if (gEarthAngle >= 360.0) // May not be > 360 { gEarthAngle -= 360.0; } gMoonAngle += (EARTH_V + 365.0 / 24.0); if (gMoonAngle >= 360.0) { gMoonAngle -= 360.0; } glutPostRedisplay(); // calls display() } //------------------------------------------------------------------------------ // The display function //------------------------------------------------------------------------------ void display(void) { char string[40]; GLint w; GLint h; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Change perspective is selected if (gPerspective) { gViewAngle += FOVY_STEP; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); reshape(w, h); } // Show current view angle sprintf(string, "fovy: %.1f", gViewAngle); renderString(10.0, 10.0, string); // Draw the scene drawSpheres(); drawCube(); glFinish(); glutSwapBuffers(); // An implicit glFlush() is done } //------------------------------------------------------------------------------ // The reshape function - also called when the window is first created //------------------------------------------------------------------------------ void reshape(int w, int h) { GLfloat aspect; if (h == 0) { h = 1; } aspect = (GLfloat)w / (GLfloat)h; glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Suppress matrix multiplication gluPerspective(gViewAngle, aspect, NEAR_PLANE, FAR_PLANE); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, -1.5, 5.0, // Eye position 0.0, 0.0, 0.0, // Where to look at 0.0, 1.0, 0.0); // y axis is up } //------------------------------------------------------------------------------ // The keyboard function //------------------------------------------------------------------------------ void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); } } //****************************************************************************** // Functions //****************************************************************************** //------------------------------------------------------------------------------ // Initialization //------------------------------------------------------------------------------ void init() { GLint w; GLint h; glEnable(GL_DEPTH_TEST); // No depth testing otherwise glClearDepth(1.0); glClearColor(0.9, 0.5, 0.0, 0.0); glShadeModel(GL_FLAT); gSelfRot = 0; gEarthAngle = 0; gMoonAngle = 0; gPerspective = 0; gViewAngle = VIEW_ANGLE; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); reshape(w, h); } //------------------------------------------------------------------------------ // Menu //------------------------------------------------------------------------------ void menu(int value) { switch (value) { case 0: exit(0); break; case 1: glutFullScreen(); break; case 2: gPerspective = !gPerspective; break; case 3: init(); break; } } void menuInit() { glutCreateMenu(menu); glutAddMenuEntry("Full screen", 1); glutAddMenuEntry("Perspective variation", 2); glutAddMenuEntry("Initialize", 3); glutAddMenuEntry("Quit", 0); glutAttachMenu(GLUT_RIGHT_BUTTON); } //------------------------------------------------------------------------------ // Drawing the objects //------------------------------------------------------------------------------ void drawSpheres(void) { /* The "sun" */ glMatrixMode(GL_MODELVIEW); glPushMatrix(); // Save current GL_MODELVIEW matrix // Rotate around all axis gSelfRot += SELF_ROT; glRotatef(gSelfRot, 1.0, 1.0, 1.0); // Rotating around each axis separately yields other effects... //glRotatef(gSelfRot, 1.0, 0.0, 0.0); // x //glRotatef(gSelfRot, 0.0, 1.0, 0.0); // y //glRotatef(gSelfRot, 0.0, 0.0, 1.0); // z // Draw axis glColor3f(0.0, 0.0, 0.0); glBegin(GL_LINES); glVertex2f(0.0, 1.5 * SUN_R); glVertex2f(0.0, -1.5 * SUN_R); glEnd(); glColor3f(1.0, 1.0, 0.0); glutWireSphere(SUN_R, 10, 12); glPopMatrix(); /* The "earth" */ glPushMatrix(); // Orbiting around the "sun" glRotatef(-gEarthAngle, 0.0, 1.0, 0.0); glTranslatef(EARTH_D, 0.0, 0.0); // Rotate around y-axis glRotatef(gSelfRot, 0.0, 1.0, 0.0); // Draw axis glBegin(GL_LINES); glVertex2f(0.0, 1.5 * EARTH_R); glVertex2f(0.0, -1.5 * EARTH_R); glEnd(); glColor3f(0.0, 0.0, 1.0); glutWireSphere(EARTH_R, 10, 10); /* The "moon" */ // Orbiting around the "earth" glRotatef(gMoonAngle, 0.0, 1.0, 0.0); glTranslatef(MOON_D, 0.0, 0.0); glColor3f(0.8, 1.0, 0.8); glutWireSphere(MOON_R, 6, 6); glPopMatrix(); } void drawCube(void) { static GLfloat angleX = 1.0; static GLfloat angleY = 10.0; static GLfloat angleZ = 5.0; glMatrixMode(GL_MODELVIEW); glPushMatrix(); // Orbiting around the "sun" glRotatef(90.0, 0.0, 0.0, 1.0); glRotatef(-gEarthAngle, 0.0, 1.0, 0.0); glTranslatef(-EARTH_D, 0.0, 0.0); // Rotate around all axis glRotatef(angleX, 1.0, 0.0, 0.0); glRotatef(angleY, 0.0, 1.0, 0.0); glRotatef(angleZ, 0.0, 0.0, 1.0); angleX += 1.0; angleY += 10.0; angleZ += 5.0; glBegin(GL_QUAD_STRIP); glColor3f(1.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, 0.5); glColor3f(1.0, 0.0, 0.0); glVertex3f(-0.5, -0.5, 0.5); glColor3f(1.0, 1.0, 1.0); glVertex3f(0.5, 0.5, 0.5); glColor3f(1.0, 1.0, 0.0); glVertex3f(0.5, -0.5, 0.5); glColor3f(0.0, 1.0, 1.0); glVertex3f(0.5, 0.5, -0.5); glColor3f(0.0, 1.0, 0.0); glVertex3f(0.5, -0.5, -0.5); glColor3f(0.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, -0.5); glColor3f(0.0, 0.0, 0.0); glVertex3f(-0.5, -0.5, -0.5); glColor3f(1.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, 0.5); glColor3f(1.0, 0.0, 0.0); glVertex3f(-0.5, -0.5, 0.5); glEnd(); glBegin(GL_QUADS); glColor3f(1.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, 0.5); glColor3f(1.0, 1.0, 1.0); glVertex3f(0.5, 0.5, 0.5); glColor3f(0.0, 1.0, 1.0); glVertex3f(0.5, 0.5, -0.5); glColor3f(0.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, -0.5); glEnd(); glBegin(GL_QUADS); glColor3f(1.0, 0.0, 0.0); glVertex3f(-0.5, -0.5, 0.5); glColor3f(1.0, 1.0, 0.0); glVertex3f(0.5, -0.5, 0.5); glColor3f(0.0, 1.0, 0.0); glVertex3f(0.5, -0.5, -0.5); glColor3f(0.0, 0.0, 0.0); glVertex3f(-0.5, -0.5, -0.5); glEnd(); glPopMatrix(); } //------------------------------------------------------------------------------ // Text output //------------------------------------------------------------------------------ void renderString(GLfloat x, GLfloat y, char* string) { // Draw the string at the given position on the screen. Positions are computed // using a 2D orthogonal projection so they can be specified in pixels. char* c; GLint w; GLint h; w = glutGet(GLUT_WINDOW_WIDTH); h = glutGet(GLUT_WINDOW_HEIGHT); // Establish orthographic projection glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); // Set a 2D orthographic projection gluOrtho2D(0, w, 0, h); // Invert the y axis, down is positive glScalef(1, -1, 1); // Move the origin from the bottom left corner to the upper left corner glTranslatef(0, -h, 0); // Now draw the text using bitmap font glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glColor3f(0.0, 0.0, 1.0); glRasterPos2f(x, y + 12.0); // Add font height in y for (c = string; *c != '\0'; c++) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, *c); } glPopMatrix(); // Restore 3D projection glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); // Set model matrix precautionary } //****************************************************************************** // Main //****************************************************************************** int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(WIDTH, HEIGHT); glutInitWindowPosition(100, 100); glutCreateWindow("First3D"); init(); menuInit(); glutIdleFunc(idle); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }