//-------------------------------------------------- // // // // Grafika Ypologiston // // Onomateponymo : Minas Gjokas // // Mitroo : 3000017 // // // // // // // //--------------------------------------------------// #include // - Windows API and system calls #include // - Just for some ASCII messages #include // - The OpenGL API #include // - The OpenGL API #include // - A windows library extension API #include // - An interface and windows // management library #include "visuals.h" // Header file for our OpenGL functions #include GLuint textures[4]; float time = 0; float step = 0.02; float pi = 3.1415927 ; float x_var = 0; float y_var = 30; float z_var = 58; // Taken from "Nehe Productions : Lesson 07 (Texture Mapping, Texture Filters)" // http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=07 AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image { FILE *File=NULL; // File Handle if (!Filename) // Make Sure A Filename Was Given { return NULL; // If Not Return NULL } File=fopen(Filename,"r"); // Check To See If The File Exists if (File) // Does The File Exist? { fclose(File); // Close The Handle return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer } return NULL; // If Load Failed Return NULL } // Taken from "Nehe Productions : Lesson 07 (Texture Mapping, Texture Filters)" // http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=07 int LoadGLTextures() // Load Bitmaps And Convert To Textures { int Status=FALSE; // Status Indicator int loop; AUX_RGBImageRec *TextureImage[4]; // Create Storage Space For The Texture memset(TextureImage,0,sizeof(void *)*4); // Set The Pointer To NULL // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit if ((TextureImage[0]=LoadBMP("models/dione.bmp")) && // Satellite Diome (TextureImage[1]=LoadBMP("models/mimas.bmp")) && // Satellite Mimas (TextureImage[2]=LoadBMP("models/saturn.bmp")) && // Planet Saturn (TextureImage[3]=LoadBMP("models/sun.bmp")) ) // Planet Sun { Status=TRUE; // Set The Status To TRUE glGenTextures(4, &textures[0]); // Create Three Textures for (loop=0; loop<4; loop++) // Loop Through All 4 Textures { glBindTexture(GL_TEXTURE_2D, textures[loop]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data); } } for (loop=0; loop<4; loop++) // Loop Through All 4 Textures { if (TextureImage[loop]) // If Texture Exists { if (TextureImage[loop]->data) // If Texture Image Exists { free(TextureImage[loop]->data); // Free The Texture Image Memory } free(TextureImage[loop]); // Free The Image Structure } } return Status; // Return The Status } void Render() { extern GLUquadricObj* sph; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(x_var,y_var,z_var, 0,0,0, 0,1,0); glEnable(GL_TEXTURE_2D); // Enable Texture Mapping /* Sun */ glBindTexture(GL_TEXTURE_2D, textures[3]); //textures[3] = texture of Sun glColor3f(1.0,1.0,0.0); //Color of Sun gluSphere(sph,5,70,70); //Using gluSphere instead of gluSolidSphere so that textures can show up Paint_Orbit(21.5, 0, /*ellipse effect*/6); //Saturn's Orbit /* Saturn */ glPushMatrix(); // glRotatef(angle, 0.0, 1.0, 0.0 ); // Rotation around the sun // glTranslatef(21.5, 0.0, 0.0); // Shift 21.5 units towards x-axis. glTranslatef(sin(time)*(21.5+6), 0.0 ,cos(time)*(21.5)); //Rotation with ellipse effect glBindTexture(GL_TEXTURE_2D, textures[2]); //textures[2] = texture of Saturn glColor3f(1.0,0.7,0.6); // Colour of Saturn gluSphere(sph,3 ,60,60); // Draw sphere Paint_Orbit(7,/*use z instead of x*/1, /*ellipse effect*/2); //Diomes Orbit Paint_Orbit(9, 0 , /*ellipse effect*/2.2); //Mimas Orbit /* Saturn 2 satellites */ /* Dione Satellite */ glPushMatrix(); // glRotatef(angle*3, 0.0, 0.0, 1.0 ); // Rotation around Saturn // glTranslatef(7.0, 0.0, 0.0); // Shift 7 units towards x-axis. glTranslatef( 0.0 ,sin(time+350)*(7+2) ,cos(time+350)*7); // y,z change glBindTexture(GL_TEXTURE_2D, textures[0]); //textures[0] = texture of Dione glColor3f(0.9,0.7,0.95); // Colour of Dione gluSphere(sph,1.8,60,70); // Draw sphere glPopMatrix(); /* Mimas Satellite */ glPushMatrix(); // glRotatef(angle*2, 0.0 , 1.0, 0.0 ); // Rotation around Saturn // glTranslatef(9.0, 0.0, 0.0); // Shift 9 units towards x-axis. glTranslatef(sin(time)*(9+2.2), 0.0 ,cos(time)*9); // x,z change glBindTexture(GL_TEXTURE_2D, textures[1]); //textures[1] = texture of Mimas glColor3f(0.8,0.9,0.9); // Colour of Mimas gluSphere(sph,1.9,60,70); // Draw sphere glPopMatrix(); /* Saturn's ring */ glEnable(GL_BLEND); // Turn Blending On glDepthMask (GL_FALSE); glBlendFunc (GL_SRC_ALPHA, GL_ONE); Paint_Ring(5.7, 4.0); // Saturn has radius 3. Nearest Satellite is Dione with radius 7. glDepthMask (GL_TRUE); glDisable(GL_BLEND); // Turn Blending Off glPopMatrix(); glDisable(GL_TEXTURE_2D); // Disable Texture Mapping glutSwapBuffers(); // Render Frame } //----------------------------------------------------------- void Idle() { extern float TranslateY; extern float v; float g; g=0.1; if (TranslateY<=0) v=-v; else v=v-g; TranslateY=TranslateY + v; time += step; glutPostRedisplay(); } //----------------------------------------------------------- void Resize(int w, int h) { // define the visible area of the window ( in pixels ) if (h==0) h=1; glViewport(0,0,w,h); // Setup viewing volume glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(50.0,(GLfloat)w / (GLfloat) h,1.0,450.0); glMatrixMode( GL_MODELVIEW ); } //----------------------------------------------------------- void Init_OpenGL() { if (!LoadGLTextures()) // Jump To Texture Loading Routine { printf("Textures not loaded"); // If Texture Didn't Load Print Message } glShadeModel( GL_SMOOTH ); // Enable Smooth Shading // Enable Depth testing, So That Objects Further Away From The // Viewer Aren't Drawn Over Closer Objects glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations glEnable(GL_NORMALIZE); // Set OpenGL To Recognise The Counter Clockwise Defined Side Of A Polygon // As Its 'Front' For Lighting And Culling Purposes glFrontFace(GL_CCW); // Enable Face Culling, So That Polygons Facing Away (Defined By Front Face) // From The Viewer Aren't Drawn (For Efficieny). glEnable(GL_CULL_FACE); //Set up light source glLoadIdentity(); GLfloat ambientLight[] = { 0.1, 0.1, 0.1, 1.0 }; // no ambient light in space GLfloat diffuseLight[] = { 0.8, 0.8, 0.8, 1.0 }; GLfloat lightPos[] = {0, 0, 0, 1.0 }; glLightfv( GL_LIGHT0, GL_AMBIENT, ambientLight ); glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseLight ); glLightfv( GL_LIGHT0, GL_POSITION, lightPos ); glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0); glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); glEnable(GL_COLOR_MATERIAL); // Black background glClearColor(0.0f,0.0f,0.0f,0.0f); // Black Background glClearDepth( 1.0f ); // Depth Buffer Setup } void Paint_Ring (float bigside, float smallside){ glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHT0); //Disable Sun's Light glPushMatrix ( ); glRotatef ( 90.0, 1.0, 0.0, 0.0 ); glColor4f(0.55,0.32,0.14,0.16); glBegin(GL_TRIANGLE_STRIP); for (int angle =0 ; angle<360;angle++){ glVertex3f((bigside+1.3)*cos(angle), bigside*sin(angle),0); //v0,v2,v4,v6, ..... glVertex3f((smallside+1.2)*cos(angle), smallside*sin(angle),0); //v1,v3,v5,v7, ..... } glEnd(); glPopMatrix ( ); glEnable(GL_LIGHT0); //Enable Sun's Light glEnable(GL_TEXTURE_2D); } void Paint_Orbit ( float radius , int angledninety, float ellipse_edit) { float angle; glDisable(GL_TEXTURE_2D); glPushMatrix ( ); glRotatef ( 90.0, 1.0, 0.0, 0.0 ); glBegin ( GL_LINE_LOOP ); glColor3f ( 0.6, 0.6, 0.7 ); for ( int i = 0; i <=72; i++ ) // More iterations are not necessary { angle = (pi / 36.0) * i; glVertex3f (!(angledninety) *(radius + ellipse_edit)*cos (angle), radius*sin (angle), angledninety* (radius + ellipse_edit)*cos ( angle )); } glEnd ( ); glPopMatrix ( ); glEnable(GL_TEXTURE_2D); } void Key_Press(unsigned char key, int x, int y) { printf( "%d\n", key); switch (key) { case 27 : exit(1); break; //Esc case 'a': case 'A': step += 0.005; break; case 's': case 'S': step -= 0.005; break; //should we check for negative time? case 'u': case 'U': y_var -= 2; break; case 'd': case 'D': y_var += 2; break; case 'l': case 'L': x_var -= 2; break; case 'r': case 'R': x_var += 2; break; case 'i': case 'I': z_var -= 2; break; case 'o': case 'O': z_var += 2; break; case 'b': case 'B': x_var = 0; y_var = 30; z_var = 58; break; } }