#pragma comment(lib, "legacy_stdio_definitions.lib")
#pragma warning(disable:4996)
#include <stdio.h>
#include <windows.h>
#include <gl\glut.h>           //OpenGL을 사용하기 위해서 헤더파일  
#include <gl\gl.h>             //OpenGL을 사용하기 위해서 헤더파일 
#include <gl\glu.h>            //OpenGL을 사용하기 위해서 헤더파일 
#include <gl\glaux.h>          //OpenGL을 사용하기 위해서 헤더파일 

#include <stdlib.h>         //exit() 함수를 이용하기위해 불러오는 헤더파일  
#include <math.h>           //renderSphere()함수안에 sin과 cos계산을 위해 불러오는 헤더파일 
#include <iostream>          
using namespace std;
static int Day[9] = { 34,223,56,123,333,154,20,170,280 }, Time[9] = { 0,0,0,0,0,0,0,0,0 };  //행성들의 공전과 자전을위해 변수선언 day의 초기화된 숫자들은 처음 시작위치를 결정  
static GLfloat Look[3] = { 1,0,4 }; //카메라 제어를 위해 변수선언 
bool flag = false;                //마우스 클릭을 위한 애니메이션 동작을 상태를 위한 값 true는 애니메이션중 false는 정지중 

GLUquadricObj *obj;             //토성 고리를 만들기위한 변수 선언   
GLUquadricObj *obj1;            //궤도를 만들기위한 변수 선언  
GLuint tex[12];                                                         //텍스쳐를 입히기 위한 변수선언 


AUX_RGBImageRec *LoadBMP(char *Filename)                                //BMP파일을 불러오는 함수  
{
 FILE *File = NULL;

 if (!Filename) return NULL;
 File = fopen(Filename, "r");
 if (File) {
  fclose(File);
  return auxDIBImageLoad(Filename);
 }
 return NULL;
}

void loadTexture()                                                  //TEXTURE를 위한 함수 
{
 AUX_RGBImageRec *texRec[11];
 memset(texRec, 0, sizeof(void *) * 11);


 if ((texRec[0] = LoadBMP("data/Sun.bmp")) &&                       //태양의 텍스쳐 로드  
  (texRec[1] = LoadBMP("data/Mercury.bmp")) &&                   //수성의 텍스쳐 로드  
  (texRec[2] = LoadBMP("data/Venus.bmp")) &&                     //금성의 텍스쳐 로드  
  (texRec[3] = LoadBMP("data/earth2.bmp")) &&                    //지구의 텍스쳐 로드  
  (texRec[4] = LoadBMP("data/Moon.bmp")) &&                      //달의 텍스쳐 로드  
  (texRec[5] = LoadBMP("data/Mars.bmp")) &&                      //화성의 텍스쳐 로드  
  (texRec[6] = LoadBMP("data/Jupiter.bmp")) &&                   //목성의 텍스쳐 로드  
  (texRec[7] = LoadBMP("data/Uranus.bmp")) &&                    //토성의 텍스쳐 로드  
  (texRec[8] = LoadBMP("data/Neptune.bmp")) &&                   //천왕성 텍스쳐 로드  
  (texRec[9] = LoadBMP("data/Pluto.bmp")) &&                     //혜왕성 텍스쳐 로드  
  (texRec+ = LoadBMP("data/Stars.bmp")))                      //주변 천체모양 텍스쳐 로드  
 {
  for (int i = 0; i<11; i++)
  {
   glGenTextures(1, &tex[i]);
   glBindTexture(GL_TEXTURE_2D, tex[i]);

   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

   glTexImage2D(GL_TEXTURE_2D, 0, 3, texRec[i]->sizeX, texRec[i]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texRec[i]->data);
  }
 }

 for (int i = 0; i<11; i++)
 {
  if (texRec[i])
  {
   if (texRec[i]->data) free(texRec[i]->data);
   free(texRec[i]);
  }
 }
 glEnable(GL_TEXTURE_2D);
 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}


void renderSphere(float cx, float cy, float cz, float r, int p) {             //구를 그리기 위한 함수  
 int i, j;
 const float PI = 3.14159265358979f;
 const float TWOPI = 6.28318530717958f;
 const float PIDIV2 = 1.57079632679489f;

 float theta1 = 0.0;
 float theta2 = 0.0;
 float theta3 = 0.0;

 float ex = 0.0f;
 float ey = 0.0f;
 float ez = 0.0f;

 float px = 0.0f;
 float py = 0.0f;
 float pz = 0.0f;

 // Disallow a negative number for radius. 
 if (r < 0)
  r = -r;

 // Disallow a negative number for precision. 
 if (p < 0)
  p = -p;

 // If the sphere is too small, just render a OpenGL point instead. 
 if (p < 4 || r <= 0) {
  glBegin(GL_POINTS);
  glVertex3f(cx, cy, cz);
  glEnd();
  return;
 }

 for (i = 0; i < p / 2; ++i) {
  theta1 = i * TWOPI / p - PIDIV2;
  theta2 = (i + 1) * TWOPI / p - PIDIV2;

  glBegin(GL_TRIANGLE_STRIP);
  {
   for (j = 0; j <= p; ++j)
   {
    theta3 = j * TWOPI / p;

    ex = cos(theta2) * cos(theta3);
    ey = sin(theta2);
    ez = cos(theta2) * sin(theta3);
    px = cx + r * ex;
    py = cy + r * ey;
    pz = cz + r * ez;

    glNormal3f(ex, ey, ez);
    glTexCoord2f(-(j / (float)p), 2 * (i + 1) / (float)p);
    glVertex3f(px, py, pz);

    ex = cos(theta1) * cos(theta3);
    ey = sin(theta1);
    ez = cos(theta1) * sin(theta3);
    px = cx + r * ex;
    py = cy + r * ey;
    pz = cz + r * ez;

    glNormal3f(ex, ey, ez);
    glTexCoord2f(-(j / (float)p), 2 * i / (float)p);
    glVertex3f(px, py, pz);
   }
  }
  glEnd();
 }
}



void InitLight()
{
 GLfloat mat_diffuse[] = { 0.5,0.4,0.3,1.0 };
 GLfloat mat_specular[] = { 1.0,1.0,1.0,1.0 };
 GLfloat mat_ambient[] = { 0.5,0.4,0.3,1.0 };
 GLfloat mat_shiniess[] = { 15.0 };
 GLfloat light_specular[] = { 1.0,1.0,1.0,1.0 };
 GLfloat light_diffuse[] = { 0.8,0.8,0.8,1.0 };
 GLfloat light_ambient[] = { 0.3,0.3,0.3,1.0 };
 GLfloat light_position[] = { 0,0,0,0 };
 glShadeModel(GL_SMOOTH);                                // 빛반사를 부드럽게 처리하기 위해 GL_SMOOTH를 넣음 
 glEnable(GL_DEPTH_TEST);
 glEnable(GL_LIGHT0);

 loadTexture();                                          // 텍스쳐 로딩  

 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
 glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
 glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shiniess);

 obj = gluNewQuadric();                                  //Quadric 객체를 생성시키는 코드이다 obj은 토성의 고리를 위해 만듬 아래쪽 함수에서 이 개체의 속성들을 정의  
 gluQuadricDrawStyle(obj, GLU_FILL);                     //obj의 속성을 결정 FILL로 되어있기때문에 SOLID형태를 띈다                  
 gluQuadricNormals(obj, GLU_SMOOTH);                     //법선벡터를 제어 벡터에의해서 빛에 대한 영향이 결정  GLU_SMOOTH이기때문에 부드럽게 처리  
 gluQuadricOrientation(obj, GLU_OUTSIDE);                //법선벡터의 방향을 지정하기 위해 사용된다 여기선 GLU_OUTSIDE를 사용  법선벡터를 물체에 대해서 바깓쪽으로 법선벡터의 방향을 지정함 
 gluQuadricTexture(obj, GL_FALSE);                       //택스쳐 맵핑 좌표생성여부 결정 GL_FALSE로 생성안함.. 

 obj1 = gluNewQuadric();                                 //위와 마찬가지로 객체를 생성시킴 obj1은 궤도를 표현하기 위해 생성 역시 아래쪽에 속성들을 정의해주는 함수를 사용.              
 gluQuadricDrawStyle(obj1, GLU_POINT);                   //궤도에는 점만으로 이루어진 디스크를 만들기 때문에 GL_POINT사용. 
 gluQuadricNormals(obj1, GLU_NONE);                      //법선벡터를 제어 벡터에의해서 빛에 대한 영향이 결정  GLU_SMOOTH이기때문에 부드럽게 처리  
 gluQuadricOrientation(obj1, GLU_OUTSIDE);               //법선벡터의 방향을 지정하기 위해 사용된다 여기선 GLU_OUTSIDE를 사용  법선벡터를 물체에 대해서 바깓쪽으로 법선벡터의 방향을 지정함 
 gluQuadricTexture(obj1, GL_FALSE);                      //택스쳐 맵핑 좌표생성여부 결정 GL_FALSE로 생성안함.. 
}

void MyDisplay()                                            //3d객체를 그리는 함수  
{
 glEnable(GL_TEXTURE_2D);                                // 
 GLfloat LightPosition[] = { 0.0,0.0,0.0,1.0 };            //빛의 위치 설정 앞에 세개는 좌표 따라서 현재 원점에서 빛이 나느것이고 뒤에 1.0은 넓게 퍼지는 빛이란뜻.  
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     //프레임 버퍼 초기화  
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();                                       //지역좌표계와 전역좌표계를 일치시켜줌                                
 gluLookAt(Look[1], Look[0], Look[2], 0, 0, -0.000010, 0, 1, 0); //카메라 시점 처음 세개의 파라미터는 카메라의 좌표 두번째 세개의 파라미터는 카메라가 보고있는 방향의 좌표 세번쩨 세개의파라미터는 카메라의 업벡터  


 glBindTexture(GL_TEXTURE_2D, tex[0]);           //밑에 태양을 그린 구에 태양 텍스쳐를 입힘  
 renderSphere(0, 0, 0, 0.3, 50);                     //태양을 그림  
 glEnable(GL_LIGHTING);                          //빛 활성화  
 glLightfv(GL_LIGHT0, GL_POSITION, LightPosition); // 빛의 위치를 설정  


 glPushMatrix();                                     //태양을 기준으로 아래처럼 수성을 그리고 스택에 푸쉬  
 glRotatef((GLfloat)Day[0], 0.0, 1.0, 0.0);         //태양을 중심으로 계속 각도를 변화시켜 회전시켜서 공전  
 glTranslatef(0.5, 0.0, 0.0);                      //태양으로부터 0.5만큼 떨어진 위치에 수성을 그린다  
 glRotatef((GLfloat)Time[0], 0.0, 1.0, 0.0);        //그리고 자전 시킨다. 
 glBindTexture(GL_TEXTURE_2D, tex[1]);           //밑에 그려진 구에 텍스쳐를 입힌다.  
 renderSphere(0, 0, 0, 0.07, 50);                    //구를 그린다.  
 glPopMatrix();                                      //그리고 다시 스텍에서 팝해온다  

 glPushMatrix();                                     //태양을 기준으로 아래처럼 금성을 그리고 스택에 푸쉬  
 glRotatef((GLfloat)Day[1], 0.0, 1.0, .0);          //태양을 중심으로 계속 각도를 변화시켜 회전시켜서 공전  
 glTranslatef(0.8, 0.0, 0.0);                      //태양으로부터 0.8만큼 떨어뜨려서 금성을 그린다.  
 glRotatef((GLfloat)Time[1], 0.0, 1.0, 0.0);        //그리고 자전을 시킨다. 
 glBindTexture(GL_TEXTURE_2D, tex[2]);           //밑에 그려진 구에 텍스쳐를 입힌다. 
 renderSphere(0, 0, 0, 0.07, 50);                    //구를 그린다.  
 glPopMatrix();                                      //그리고 다시 스텍에서 팝해온다. 

 glPushMatrix();                                     //태양을 기준으로 아래처럼 지구를 그리고 스택에 푸쉬  
 glRotatef((GLfloat)Day[2], 0.0, 1.0, 0.0);         //태양을 중심으로 계속 각도를 변화시켜 회전시켜서 공전  
 glTranslatef(1.1, 0.0, 0.0);                      //태양으로부터 1.1만큼 떨어진위치에 지구를 그린다. 
 glRotatef((GLfloat)Time[2], 0.0, 1.0, 0.0);        //그리고 자전을 시키고 
 glBindTexture(GL_TEXTURE_2D, tex[3]);           //아래에 그려진 구에 텍스쳐를 입힌다. 
 renderSphere(0, 0, 0, 0.07, 50);                    //구 그리기 . 
 glPushMatrix();                                 //지구를 기준으로 아래처럼 달을 그리고 스택에 푸쉬  
 glTranslatef(0.12, 0.0, 0.0);                 //지구에서 0.12만큼 떨어진 위치에 
 glBindTexture(GL_TEXTURE_2D, tex[4]);       //달 덱스쳐를 입히고 
 renderSphere(0, 0, 0, 0.01, 50);                //구를 그림  
 glPopMatrix();                                  //달을 스택에서 팝해온다.. 
 glPopMatrix();                                      //지구를 스택에서 팝해온다  

 glPushMatrix();                                     //태양을 기준으로 아래처럼 화성을 그리고 스택에 푸쉬  
 glRotatef((GLfloat)Day[3], 0.0, 1.0, 0.0);         //태양을 중심으로 계속 각도를 변화시켜 회전시켜서 공전  
 glTranslatef(1.4, 0.0, 0.0);                      //태양으로부터 1.4만큼 떨어진위치에 화성을 그린다. 
 glRotatef((GLfloat)Time[3], 0.0, 1.0, 0.0);        //자전을 시킨다. 
 glBindTexture(GL_TEXTURE_2D, tex[5]);           //아래 그려진 구에 텍스쳐를 입힌다. 
 renderSphere(0, 0, 0, 0.07, 50);                    //구를 그린다. 
 glPopMatrix();                                      //스택에 저장된 화성을 팝해온다. 

 glPushMatrix();                                     //태양을 기준으로 아래처럼 목성을 그리고 스택에 푸쉬   
 glRotatef((GLfloat)Day[4], 0.0, 1.0, 0.0);         //태양을 중심으로 계속 각도를 변화시켜 회전시켜서 공전  
 glTranslatef(1.7, 0.0, 0.0);                      //태양으로부터 1.7만큼 떨어진곳에 목성을 생성. 
 glRotatef((GLfloat)Time[4], 0.0, 1.0, 0.0);        //자전을 시킨다. 
 glBindTexture(GL_TEXTURE_2D, tex[6]);           //아래그려진 구에 텍스쳐를 입힌다. 
 renderSphere(0, 0, 0, 0.12, 50);                    //구를 그린다. 
 glPopMatrix();                                      //스택에 저장된 목성을 팝해온다. 

 glPushMatrix();                                     //태양을 기준으로 아래처럼 토성을 그리고 스택에 푸쉬   
 glRotatef((GLfloat)Day[5], 0.0, 1.0, 0.0);         //태양을 중심으로 계속 각도를 변화시켜 회전시켜서 공전  
 glTranslatef(2.1, 0.0, 0.0);                      //태양으로부터 2.1만큼 떨어진곳에 토성을 생성. 
 glRotatef(45, 1.0, 0.0, 0.0);                      //토성을 45도 기울임  
 glDisable(GL_LIGHTING);                         //고리에 색이 잘 보이기위해 광원효과를 임시로 끔.  
 glColor3f(0.0, 1.0, 1.0);                         //고리의 색  
 gluDisk(obj, 0.135, 0.140, 16, 4);              //고리를 그림  
 glColor3f(0.5, 1.0, 1.0);                         // 여러가지 색을 넣기위해 여러번 고리를 점차 크게 그림  
 gluDisk(obj, 0.140, 0.145, 16, 4);
 glColor3f(0.2, 1.0, 0.2);
 gluDisk(obj, 0.145, 0.150, 16, 4);
 glColor3f(0.0, 1.0, 1.0);
 gluDisk(obj, 0.150, 0.155, 16, 4);
 glColor3f(1.0, 1.0, 1.0);
 gluDisk(obj, 0.155, 0.160, 16, 4);
 glColor3f(0.2, 1.0, 1.7);
 gluDisk(obj, 0.160, 0.165, 16, 4);
 glColor3f(1.0, 0.5, 1.0);
 gluDisk(obj, 0.165, 0.170, 16, 4);
 glColor3f(0.3, 1.0, 1.0);
 gluDisk(obj, 0.170, 0.175, 16, 4);
 glColor3f(1.0, 1.0, 1.0);
 gluDisk(obj, 0.175, 0.180, 16, 4);
 glColor3f(0.4, 1.0, 1.0);
 gluDisk(obj, 0.180, 0.185, 16, 4);
 glEnable(GL_LIGHTING);                          //임시로 끈 광원효과를 다시 켬  
 glRotatef((GLfloat)Time[5], 0.0, 1.0, 0.0);        //고리는 가만히 있고 토성 자체만 자전시킴  
 glBindTexture(GL_TEXTURE_2D, tex[7]);           //아래그려진 토성에 택스쳐 입힘. 
 renderSphere(0, 0, 0, 0.12, 50);                    //구를 그림  

 glPopMatrix();                                      //저장된 스택에서 꺼내옴. 

 glPushMatrix();                                     //태양을 기준으로 아래처럼 천왕성을 그리고 스택에 푸쉬  
 glRotatef((GLfloat)Day[6], 0.0, 1.0, 0.0);         //태양을 중심으로 계속 각도를 변화시켜 회전시켜서 공전 
 glTranslatef(2.5, 0.0, 0.0);                      //태양으로부터 2.5만큼 떨어진위치에 화성을 그린다. 
 glRotatef((GLfloat)Time[6], 0.0, 1.0, 0.0);        //천왕성을 자전시킴  
 glBindTexture(GL_TEXTURE_2D, tex[8]);           //아래그려진 구에 택스쳐를 입힘. 
 renderSphere(0, 0, 0, 0.07, 50);                    //구를 그림  
 glPopMatrix();                                      //저장된 스택에서 꺼내옴  

 glPushMatrix();                                     //태양을 기준으로 아래처럼 혜왕성을 그리고 스택에 푸쉬  
 glRotatef((GLfloat)Day[7], 0.0, 1.0, 0.0);         //태양을 중심으로 계속 각도를 변화시켜 회전시켜서 공전 
 glTranslatef(3.0, 0.0, 0.0);                      //태양으로부터 3.0만큼 떨어진위치에 그린다. 
 glRotatef((GLfloat)Time[7], 0.0, 1.0, 0.0);        //자전을 시킨다. 
 glBindTexture(GL_TEXTURE_2D, tex[9]);           //아래 그려진 구에 택스쳐를 입힘. 
 renderSphere(0, 0, 0, 0.07, 50);                    //구를 그림 
 glPopMatrix();                                      //저장된 스택에서 꺼내옴. 

 glPushMatrix();                                     //태양을 중심으로 궤도와 천체 별들이 그려질 구를 그려 스택에 저장  
 glDisable(GL_LIGHTING);                             //조명효과를 끔. 궤도 색상이 잘나오게 하기 위해  
 glRotatef(90, 1.0, 0.0, 0.0);                          //궤도를 90도 회전시켜서 실제 공전궤도와 일치시킴  
 glColor3f(1, 1, 1);                                   //궤도의 색을 밝은색으로 바꿈  
 gluDisk(obj1, 0.5, 0.5, 110, 1);                    //수성궤도  InitLight()함수에서 설정한 obj1을 불러와서 점으로된 디스크를 그리기  
 gluDisk(obj1, 0.8, 0.8, 120, 1);                    //금성궤도  
 gluDisk(obj1, 1.1, 1.1, 130, 1);                    //지구 궤도  
 gluDisk(obj1, 1.4, 1.4, 140, 1);                    //화성 궤도  
 gluDisk(obj1, 1.7, 1.7, 150, 1);                    //목성 궤도  
 gluDisk(obj1, 2.1, 2.1, 160, 1);                    //토성 궤도  
 gluDisk(obj1, 2.5, 2.5, 170, 1);                    //천왕성 궤도   
 gluDisk(obj1, 3.0, 3.0, 180, 1);                    //혜왕성 궤도  
 glRotatef(90, 1.0, 0.0, 0.0);                          //태양계를 제외한 천체를 90도 회전 (그대로 놔두면 텍스쳐가 모이는곳이 보임 미관상...) 
 glBindTexture(GL_TEXTURE_2D, tex+);              //커다란 구를 그려 거기에 우주텍스쳐를 씌워서 별이 보이게 만든다 
 renderSphere(0, 0, 0, 18.0, 50);                        //커다란 구를 그림  
 glPopMatrix();                                          //스택에 저장된 궤도들을 불러옴  

 glutSwapBuffers();                                      //2중 버퍼링을 쓰기위한 함수  
 glFlush();
}

void MyTimer(int Value)
{
 //공전주기 계산 glRoteatef함수에 들어가기 위해 계산 함 360도로 계속 나눠서 나머지를 값에 대입  


 Time[0] = (Time[0] + 1) % 360;
 Time[1] = (Time[1] + 2) % 360;
 Time[2] = (Time[2] + 3) % 360;
 Time[3] = (Time[3] + 2) % 360;
 Time[4] = (Time[4] + 1) % 360;
 Time[5] = (Time[5] + 2) % 360;
 Time[6] = (Time[6] + 2) % 360;
 Time[7] = (Time[7] + 1) % 360;

 //자전 주기  
 Day[0] = (Day[0] + 4) % 360;
 Day[1] = (Day[1] + 3) % 360;
 Day[2] = (Day[2] + 1) % 360;
 Day[3] = (Day[3] + 2) % 360;
 Day[4] = (Day[4] + 1) % 360;
 Day[5] = (Day[5] + 1) % 360;
 Day[6] = (Day[6] + 2) % 360;
 Day[7] = (Day[7] + 1) % 360;


 glutPostRedisplay();                    // 화면을 다시 모니터에 뿌려줌 
 if (flag == true)                        //애니메이션 상태값 flag가 ture라면  
 {
  glutTimerFunc(30, MyTimer, 1);        //계속 재귀호출하여 에니메이션을 동작시킴  
 }
}

void MyMouseClick(GLint Button, GLint State, GLint X, GLint Y)
{
 if (Button == GLUT_LEFT_BUTTON && State == GLUT_DOWN) //마우스 오른쪽 버튼이 눌러졌을때 
 {
  if (flag == false)                             //애니메이션 상태값 flag가 false라면 
  {
   flag = true;                              // 상태값을 ture로 변환후 
   glutTimerFunc(10, MyTimer, 1);            // 타이머 함수 호출  
  }
  else                                        // 상태값이 ture라면  
   flag = false;                             // 상태값을 false로 바꿔서 애니메이션을 멈춤 
 }
}

void MySpecialKey(int key, int x, int y)      //특수키 동작 
{
 switch (key)
 {
 case GLUT_KEY_UP:                      //방향키 위쪽을 누를때 
  if (Look[0] < 8)                      //카메라 동작 한계범위안에 있다면  
   Look[0] += 0.1;                   //값을 증가시켜 카메라를 위로 올림  
  glutPostRedisplay();                //화면을 다시그려줌 
  break;
 case GLUT_KEY_DOWN:                    //방향키 아래쪽을 누를때 
  if (Look[0] > -8)                 //카메라 동작 한계범위안에 있다면  
   Look[0] -= 0.1;                   //값을 감소시켜 카메라를 아래로 내림  
  glutPostRedisplay();                //화면을 다시그려줌              
  break;
 case GLUT_KEY_LEFT:                    //방향키 왼쪽을 누를때 
  if (Look[1] < 8)                      //카메라 동작 한계범위안에 있다면  
   Look[1] += 0.05;                  //값을 증가시켜 카메라를 왼쪽으로 이동 
  glutPostRedisplay();                //화면을 다시그려줌 
  break;
 case GLUT_KEY_RIGHT:                   //방향키 오른족을 누를때 
  if (Look[1] > -8)                    //카메라 동작 한계범위안에 있다면  
   Look[1] -= 0.05;                  //값을 감소시켜 카메라를 오른쪽으로 이동 
  glutPostRedisplay();                //화면을 다시그려줌 
  break;
 case GLUT_KEY_PAGE_UP:                 //Page Up키를 누를때  
  if (Look[2] < 10)                    //카메라 동작 한계범위안에 있다면  
   Look[2] += 0.05;                  //값을 증가시켜 줌아웃  
  glutPostRedisplay();                //화면을 다시그려줌 
  break;
 case GLUT_KEY_PAGE_DOWN:               //Page Down키를 누를때  
  if (Look[2] > 1)                     //카메라 동작 한계범위안에 있다면  
   Look[2] -= 0.05;                  //값을 감소시켜 줌인  
  glutPostRedisplay();                //화면을 다시그려줌 
  break;
 default:
  break;
 }
}


void MyKeyboard(unsigned char key, int x, int y)  //일반 키보드 동작 
{
 switch (key) {
 case 'q':                                       //q나 Q키를 눌렀을경우 프로그램 종료 
  exit(0);
 case 'Q':
  exit(0);
 default:
  break;
 }
}

void MyReshape(int w, int h)
{
 glViewport(0, 0, (GLsizei)w, (GLsizei)h);           //뷰포트 크기를 변경된 윈도우 크기와 일치시켜 윈도우내의 어느곳이라도 물체를 그릴수 있게 해줌  
 glMatrixMode(GL_PROJECTION);
 gluPerspective(30, 1.33, 0.001, 200.0);                //투상법으로서 맨앞에 30은 시야를 설정 다음은 y축방향 시야각 그다음으느 뷰윈도우의 종횡비이다.  
                 // 0.001은 전방 절단면 200은 후방 절단면이다.  
}

int main(int argc, char** argv)
{
 glutInit(&argc, argv);                                                   //GLUT 라이브러리를 초기화시키고 윈도우 운영체제와 연결 하기 위한 함수 
 glutInitDisplayMode(GLUT_RGB | GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);   //윈도우 컬러모드와 그래픽 카드 더블버퍼링 초기화  
 glutInitWindowSize(800, 600);                                            //윈도우 창 사이즈 결정  
 glutInitWindowPosition(0, 0);                                            //윈도우 위치 설정  
 glutCreateWindow("OpenGl Drawing Example");                             //윈도우 제목 설정 
 glClearColor(0.0, 0.0, 0.0, 0.0);                                          //배경색 설정  
 InitLight();

 loadTexture();
 glutDisplayFunc(MyDisplay);                                             //3d객체들을 그려놓은 함수  
 glutKeyboardFunc(MyKeyboard);                                           //키보드 제어를 함  
 glutSpecialFunc(MySpecialKey);                                          //특수키 제어를 함   
 glutMouseFunc(MyMouseClick);                                            //마우스 클릭 제어  
 glutReshapeFunc(MyReshape);                                             //사용자가 윈도우 크기를 조절한 결과 GLUT가 읽어들인 윈도우폭과 높이 파라미터를 이용하여 원하는 작업을 하기 위한 함수  
 glutSwapBuffers();                                                      //2중버퍼.. 
 glutMainLoop();                                                         //3d를 계속 화면에 뿌려주기위한 루프  
 return 0;
}

파일들도 다들어가있고 문법문제는 없는거같은데 돌리면

1>소스.obj : error LNK2019: auxDIBImageLoadA 외부 기호(참조 위치: "struct _AUX_RGBImageRec * __cdecl LoadBMP(char *)" (?LoadBMP@@YAPEAU_AUX_RGBImageRec@@PEAD@Z) 함수)에서 확인하지 못했습니다.
1>c:\users\yuki\documents\visual studio 2015\Projects\ConsoleApplication6\x64\Debug\ConsoleApplication6.exe : fatal error LNK1120: 1개의 확인할 수 없는 외부 참조입니다.

자꾸이게뜨네ㅠㅠ 해결법아는사람있으면 답글좀제발부탁이야