3D Planetary System In OpenGL

    
 
   
 
    
 
Well you all know our planetary system, it has one sun and many planets revolving around the sun. To draw all these objects with textures first you need to have the textured images of that object. You can download all these images on Google Images and modify them.
 
The textured image must have the following properties:

Extension 24 Color Bitmap(.bmp)
Dimensions 256*256
Bit Depth24

You can edit or change the dimension and extension of images by using simple Paint application in Windows. Download the source code for code & images.
 
Ok now you have all images for your planets. Now start Visual Studio and configure it for glut library. Don't know how to configure Visual Studio for glut?
All right, now you have configured the Visual Studio for glut, now let's move to the coding. First you need to create the function that sets texture to the object. I am using LoadTextureImageFile(const char * filename) function that takes a char pointer parameter.
Here's the code for adding texture to the object.
  1. GLuint LoadTextureImageFile(const char * filename)  
  2. {  
  3.     GLuint texture = 0;  
  4.     int width, height;  
  5.     BYTE * data = NULL;  
  6.     FILE * file;  
  7.   
  8.     // open texture data  
  9.     fopen_s(&file, filename, "rb");  
  10.   
  11.     if (&file == NULL) return 0;  
  12.   
  13.     // allocate buffer  
  14.     width = 256;  
  15.     height = 256;  
  16.   
  17.     data = (BYTE*)malloc(width * height * 3);  
  18.   
  19.     // read texture data  
  20.     fread(data, width * height * 3, 1, file);  
  21.     fclose(file);  
  22.   
  23.     glGenTextures(1, &texture);  
  24.   
  25.     glBindTexture(GL_TEXTURE_2D, texture);  
  26.   
  27.     //  texture MIP maps  
  28.     gluBuild2DMipmaps(GL_TEXTURE_2D, GL_BGRA_EXT, width, height, GL_BGR_EXT, GL_UNSIGNED_BYTE, data);  
  29.   
  30.   
  31.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_TEXTURE_ENV_COLOR);  
  32.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  
  33.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);  
  34.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);  
  35.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);  
  36.   
  37.     // free buffer  
  38.     free(data);  
  39.   
  40.     return texture;  
  41.   
  42. }  
  43.   
  44.   
  45. void FreeCreatedTexture(GLuint texture)  
  46. {  
  47.     glDeleteTextures(1, &texture);  
  48. }   
Description
 
The above function returns the build texture having data type GLuint. First read the image file & fread that data to the declared variable of BYTE. Then call glGenTextures() & glBindTexture() methods for binding read data from image. Then build the 2D Mipmaps that sets the color & texture to the object. We are using 256*256 image dimension so width & height will be 256 respectively. Remember our image is of bitmap(.bmp) type, so to use the color of image you must set GL_BGRA_EXT instead of GL_RGBA_EXT because .bmp images store the image data in the Blue-Green-Red(BGR) format not in RGB. Then you can set your own parameters for drawing textured image objects.

FreeCreatedTexture() function release all texture data from memory. 
 
Example
 
Consider you want to draw a textured square. The following function draws a textured square.
 
First call above function & pass image filename as a parameter(e.g : rocks.bmp).
 
Then call glEnable(GL_TEXTURE_2D) for enabling the image texture.
 
Then call glBindTexture(GL_TEXTURE_2D,GLuint texturedata).
 
You can draw the texture of any object by using glTexCoord2f(x,y) method.
 
Remember x & y are not co-ordinates,they set the texture to object according to the x and y values. 
  1. glPushMatrix();  
  2.   
  3. GLuint texture = LoadTextureImageFile("textures/rocks.bmp");  
  4.   
  5. glEnable(GL_TEXTURE_2D);  
  6. glBindTexture(GL_TEXTURE_2D, texture);  
  7.   
  8. glBegin(GL_QUADS);  
  9. glTexCoord2f(0.0, 0.0);  
  10. glVertex3f(-2.0, 2.0, 0.0);  
  11. glTexCoord2f(0.0, 1.0);  
  12. glVertex3f(2.0, 2.0, 0.0);  
  13. glTexCoord2f(1.0, 1.0);  
  14. glVertex3f(2.0, -2.0, 0.0);  
  15. glTexCoord2f(1.0, 0.0);  
  16. glVertex3f(-2.0, -2.0, 0.0);  
  17. glEnd();  
  18.   
  19. glPopMatrix();   
Ok now you have set the function that added texture to the object, now let's move to draw the object.

Let's draw a sun,
 
To draw a textured sphere use gluSphere() function instead of glutSolidSphere(). To enable the texture for sphere, first you need to define GLUquadric pointer variable and assign memory to it by calling gluNewQuadric() function. Then call gluQuadricTexture() & pass the created GLUquadric pointer variable. Then call the gluSphere() method.

See the following code for better understanding. Code draws a textured sphere, which  means our sun.
  1. GLuint texture = LoadTextureImageFile("textures/sun.bmp");  
  2.   
  3. GLUquadric *quad;  
  4.   
  5. glPushMatrix();  
  6.   
  7. //draw sun  
  8. glEnable(GL_TEXTURE_2D);  
  9. glBindTexture(GL_TEXTURE_2D, texture);  
  10.   
  11. quad = gluNewQuadric();  
  12. gluQuadricTexture(quad, 40);  
  13.   
  14. glTranslatef(0.0, 0.0, 0.0);  
  15.   
  16. glRotatef((GLfloat)sun, 0.0, 1.0, 0.0);  
  17. gluSphere(quad, 30.0, 100, 100);  
  18.   
  19. glPopMatrix();   
To disable texture for next drawn object use glDisable(GL_TEXTURE_2D) method.
 
Using the same code that we used to draw the sun, you can draw planets. Download the source code.

Here's the code that draws the earth.
  1. glPushMatrix();  
  2.   
  3. glEnable(GL_TEXTURE_2D);  
  4.   
  5. texture = LoadTextureImageFile("textures/earth.bmp");  
  6. glBindTexture(GL_TEXTURE_2D, texture);  
  7.   
  8. quad = gluNewQuadric();  
  9. gluQuadricTexture(quad, 1);  
  10. glTranslatef(0.0, 0.0,  120.0);  
  11. glRotatef((GLfloat)planet, 0.0, 1.0, 0.0);  
  12. gluSphere(quad, 5.0, 70, 70);  
  13.   
  14. FreeCreatedTexture(texture);  
  15.   
  16. glPopMatrix();   
You can also rotate or orient the whole scene by rotating the camera. This can be done by using gluLookAt() function. First declare the variables for your default camera position.
  1. float _Angle = 0.0;  
  2. float _moveLeftRight = 0.0;  
  3. float X = -5.0, Z = 150.0;  
  4. float X_2 = 0.0, Z_2 = -1.0;  
  5. float Y = 3.0;  
  6. int _moveForeBack = 0;  
  7. int moveUp = 0;   
Following function rotate you to Left or Right direction when Left or Right key is pressed respectively. 
  1. void Moving_Left_Right_Direction(float angle)  
  2. {  
  3.     X_2 = sin(angle);  
  4.     Z_2 = -cos(angle);  
  5.     glLoadIdentity();  
  6.     gluLookAt(X, Y, Z, X + X_2, Y, Z + Z_2, 0.0f, 1.0f, 0.0f);  
  7. }   
Following function moves you to Foreward or Backward when Up or Down key is pressed respectively. 
  1. void Moving_Foreword_Backword_Direction(int loc)  
  2. {  
  3.     X = X + loc*(X_2)*fb;  
  4.     Z = Z + loc*(Z_2)*fb;  
  5.     glLoadIdentity();  
  6.     gluLookAt(X, Y, Z, X + X_2, Y, Z + Z_2, 0.0f, 1.0f, 0.0f);  
  7. }   
Here's the code for key pressed & key released function.
  1. //keyboard key pressed function  
  2. void Key_Pressed(int key, int x, int y)  
  3. {  
  4.     if (key == GLUT_KEY_LEFT)  
  5.     {  
  6.         _moveLeftRight = -0.09;  
  7.     }  
  8.     else if (key == GLUT_KEY_RIGHT)  
  9.     {  
  10.         _moveLeftRight = 0.09;  
  11.     }  
  12.     else if (key == GLUT_KEY_UP)  
  13.     {  
  14.         _moveForeBack = 8;  
  15.     }  
  16.     else if (key == GLUT_KEY_DOWN)  
  17.     {  
  18.         _moveForeBack = -8;  
  19.     }  
  20.     else if (key == GLUT_KEY_UP && key == GLUT_KEY_LEFT)  
  21.     {  
  22.         _moveLeftRight = 0.07;  
  23.     }  
  24.     else if (key == GLUT_KEY_UP && key == GLUT_KEY_RIGHT)  
  25.     {  
  26.         _moveLeftRight = 0.07;  
  27.     }  
  28.     else if (key == GLUT_KEY_PAGE_UP)  
  29.     {  
  30.         Y += 2.0;  
  31.         glLoadIdentity();  
  32.         gluLookAt(X, Y, Z, X + X_2, Y, Z + Z_2, 0.0f, 1.0f, 0.0f);  
  33.         glutPostRedisplay();  
  34.     }  
  35.     else if (key == GLUT_KEY_PAGE_DOWN)  
  36.     {  
  37.         Y -= 2.0;  
  38.         glLoadIdentity();  
  39.         gluLookAt(X, Y, Z, X + X_2, Y, Z + Z_2, 0.0f, 1.0f, 0.0f);  
  40.         glutPostRedisplay();  
  41.     }  
  42.   
  43. }  
  44.   
  45.   
  46. //keyboard key released function  
  47. void Key_Released(int key, int x, int y)  
  48. {  
  49.     switch (key)  
  50.     {  
  51.     case GLUT_KEY_LEFT:  
  52.         if (_moveLeftRight < 0.0f)  
  53.             _moveLeftRight = 0.0f;  
  54.         break;  
  55.   
  56.     case GLUT_KEY_RIGHT:  
  57.         if (_moveLeftRight > 0.0f)  
  58.             _moveLeftRight = 0.0f;  
  59.         break;  
  60.   
  61.     case GLUT_KEY_UP:  
  62.         if (_moveForeBack > 0)  
  63.             _moveForeBack = 0;  
  64.   
  65.         break;  
  66.   
  67.     case GLUT_KEY_DOWN:  
  68.         if (_moveForeBack < 0)  
  69.             _moveForeBack = 0;  
  70.         break;  
  71.     }  
  72. }   
To use above key functions use following methods in main method.

glutSpecialFunc(Key_Pressed);
glutSpecialUpFunc(Key_Released);
 
To go to the Full screen mode call glutFullScreen() method before glutMainLoop() method.