wisdiom 아니고 wisdom

[실습 15] 태양계 애니메이션 본문

👩‍💻/OpenGL

[실습 15] 태양계 애니메이션

글로랴 2021. 6. 30. 20:34

🔍 중심에 있는 구(태양)를 중심으로 3개의 구(각기 다른 행성)가 다른 방향의 경로를 따라 회전하는 애니메이션 제작. 각 구에는 그 구를 중심으로 달이 공전한다.

 

#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>



void drawscene();
void Reshape(int w, int h);
void Keyboard(unsigned char key, int x, int y);
void MenuFunc(int);
void MyTimer(int);

​

bool wire = false;

​

static GLfloat directX = 0.0;
static GLfloat directY = 0.0;
static GLfloat directZ = 0.0;
static GLfloat angleZ = 0.0;

​

static int planet1 = 0.f;
static int planet2 = 0.0f;
static int planet3 = 0.0f;
static int Luna = 0.0f;

const int fps = 10;

​

int main()
{
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
 glutInitWindowPosition(300, 100);
 glutInitWindowSize(800, 600);
 glutCreateWindow("컴그_실습15");
 glutKeyboardFunc(Keyboard);
 glutDisplayFunc(drawscene);
 glutReshapeFunc(Reshape);

​

 int mainmenu;​

 mainmenu = glutCreateMenu(MenuFunc);
 glutAddMenuEntry("Solid", 1);
 glutAddMenuEntry("Wire", 2);
 glutAddMenuEntry("Exit", 3);
 glutAttachMenu(GLUT_RIGHT_BUTTON);

​

 glutTimerFunc(fps, MyTimer, 1);
 glutMainLoop();

}

​

void Reshape(int w, int h)
{
 //GLfloat nRange = 800.0f;

 // 뷰포트 변환 설정
 glViewport(0, 0, w, h);

 // 투영 행렬 스택 재설정
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();

 gluPerspective(60.0f, w / h, 1.0, 1000.0);
 glTranslatef(0.0, 0.0, -300.0);

 glMatrixMode(GL_MODELVIEW);   //모델 뷰 행렬 스택 재설정
 glLoadIdentity();
 glTranslatef(directX, 0.0, 0.0);
 glTranslatef(0.0, directY, 0.0);
 glTranslatef(0.0, 0.0, directZ);
 glRotatef(angleZ, 0.0, 0.0, 1.0);

  // 카메라   *관측 변환: 카메라의 위치 설정 (필요한 경우, 다른 곳에 설정 가능)
 gluLookAt(0.0, 3.0, 0.0, 0.0, 0.0, -15.0, 0.0, 1.0, 0.0);

 glViewport(0, 0, w, h);
}

​

void Keyboard(unsigned char key, int x, int y)
{
 switch (key)
 {
 case 'x':
  directX += 1.0;
  break;
 case 'X':
  directX -= 1.0;
  break;
 case 'y':
  directY += 1.0;
  break;
 case 'Y':
  directY -= 1.0;
  break;
 case'z':
  angleZ += 1.0;
  break;
 case'Z':
  angleZ -= 1.0;
  break;
 case '+':
  directZ += 1.0;
  break;
 case'-':
  directZ -= 1.0;
  break;
 case 'i':
  directX = 0.0;
  directY = 0.0;
  directZ = 0.0;
  angleZ = 0.0;
  break;
 default:
  break;
 }
 Reshape(800, 600);
 glutPostRedisplay();
}

​

void drawscene()
{
 glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // 바탕색 흰 색
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 // 초기화

 // --- XZ축 원 궤도
 glColor3f(0.0, 0.0, 0.0);

 glBegin(GL_LINE_LOOP);
 for (int degree = 0; degree < 360; degree += 1)
 {
  float radian = (float)degree*3.141592f / 180.f;
  glVertex3f(sin(radian) * 80, 0.0, cos(radian) * 80);
 }
 glEnd();

 // 시계방향 45도
 glPushMatrix();
 glRotatef(45, 0.0, 0.0, 1.0);
 glBegin(GL_LINE_LOOP);
 for (int degree = 0; degree < 360; degree += 1)
 {
  float radian = (float)degree*3.141592f / 180.f;
  glVertex3f(sin(radian) * 80, 0.0, cos(radian) * 80);
 }
 glEnd();
 glPopMatrix();

 // 반시계방향 45도
 glPushMatrix();
 glRotatef(-45, 0.0, 0.0, 1.0);
 glBegin(GL_LINE_LOOP);
 for (int degree = 0; degree < 360; degree += 1)
 {
  float radian = (float)degree*3.141592f / 180.f;
  glVertex3f(sin(radian) * 80, 0.0, cos(radian) * 80);
 }
 glEnd();
 glPopMatrix();

 // 와이어 모델
 if (wire == true)
 {
  //중심 구
  glPushMatrix();
  glTranslatef(0.0, 5.0, 0.0);
  glLineWidth(1);
  glColor3f(1.0f, 0.0f, 0.0f);
  glutWireSphere(13, 10, 10);
  glPopMatrix();

  // xy평면 구
  glPushMatrix();
  {
   glRotatef((GLfloat)planet1, 0.0, 1.0, 0.0);
   glTranslatef(-70.0, 0.0, -30.0);
   glRotatef((GLfloat)Luna, 0.0, 1.0, 0.0);
   glColor3f(0.0f, 0.0f, 1.0f);
   glutWireSphere(5, 10, 10);

   // 달 궤도
   glPushMatrix();
   {
    glColor3f(0.0, 0.0, 0.0);
    glBegin(GL_LINE_LOOP);
    for (int degree = 0; degree < 360; degree += 1)
    {

     float radian = (float)degree*3.141592f / 180.f;
     glVertex3f(sin(radian) * 20, 0.0, cos(radian) * 20);
    }
    glEnd();
   }
   glPopMatrix();
   // 달
   glPushMatrix();
   {
    glRotatef((GLfloat)Luna, 0.0, 1.0, 0.0);
    glTranslatef(-1.0, 0.0, -20.0);
    glColor3f(1.0f, 1.0f, 0.0);
    glutWireSphere(2, 5, 5);
   }
   glPopMatrix();
  }
  glPopMatrix();

  // xy 시계방향 구
  glPushMatrix();
  {
   glRotatef(45.0, 0.0, 0.0, 1.0);
   glRotatef((GLfloat)planet2, 0.0, 1.0, 0.0);
   glTranslatef(30.0, 0.0, 75.0);
   glRotatef((GLfloat)Luna, 0.0, 1.0, 0.0);
   glColor3f(0.5f, 1.0f, 0.8f);
   glutWireSphere(5, 10, 10);

   // 달 궤도
   glPushMatrix();
   {
    glColor3f(0.0, 0.0, 0.0);
    glBegin(GL_LINE_LOOP);
    for (int degree = 0; degree < 360; degree += 1)
    {

     float radian = (float)degree*3.141592f / 180.f;
     glVertex3f(sin(radian) * 20, 0.0, cos(radian) * 20);
    }
    glEnd();
   }
   glPopMatrix();
   // 달
   glPushMatrix();
   {
    glRotatef((GLfloat)Luna, 0.0, 1.0, 0.0);
    glTranslatef(-1.0, 0.0, -20.0);
    glColor3f(1.0f, 1.0f, 0.0);
    glutWireSphere(2, 5, 5);
   }
   glPopMatrix();
  }
  glPopMatrix();

  // xy 반시계방향 구
  glPushMatrix();
  {
   glRotatef(-45.0, 0.0, 0.0, 1.0);
   glRotatef((GLfloat)planet3, 0.0, 1.0, 0.0);
   glTranslatef(30.0, 0.0, 75.0);
   glRotatef((GLfloat)Luna, 0.0, 1.0, 0.0);
   glColor3f(0.0f, 1.0f, 0.0f);
   glutWireSphere(5, 10, 10);

   // 달 궤도
   glPushMatrix();
   {
    glColor3f(0.0, 0.0, 0.0);
    glBegin(GL_LINE_LOOP);
    for (int degree = 0; degree < 360; degree += 1)
    {

     float radian = (float)degree*3.141592f / 180.f;
     glVertex3f(sin(radian) * 20, 0.0, cos(radian) * 20);
    }
    glEnd();
   }
   glPopMatrix();
   // 달
   glPushMatrix();
   {
    glRotatef((GLfloat)Luna, 0.0, 1.0, 0.0);
    glTranslatef(-1.0, 0.0, -20.0);
    glColor3f(1.0f, 1.0f, 0.0);
    glutWireSphere(2, 5, 5);
   }
   glPopMatrix();
  }
  glPopMatrix();
 }

 // 솔리드 모델
 else
 {
  //중심 구
  glPushMatrix();
  glTranslatef(0.0, 5.0, 0.0);
  glColor3f(1.0f, 0.0f, 0.0f);
  glutSolidSphere(13, 100, 100);
  glPopMatrix();

  // xy평면 구
  glPushMatrix();
  {
   glLineWidth(1);
   glRotatef((GLfloat)planet1, 0.0, 1.0, 0.0);
   glTranslatef(-70.0, 0.0, -30.0);
   glRotatef((GLfloat)Luna, 0.0, 1.0, 0.0);
   glColor3f(0.0f, 1.0f, 1.0f);
   glutSolidSphere(5, 100, 100);
   // 달 궤도
   glPushMatrix();
   {
    glColor3f(0.0, 0.0, 0.0);
    glBegin(GL_LINE_LOOP);
    for (int degree = 0; degree < 360; degree += 1)
    {
     float radian = (float)degree*3.141592f / 180.f;
     glVertex3f(sin(radian) * 20, 0.0, cos(radian) * 20);
    }
    glEnd();
   }
   glPopMatrix();
   // 달
   glPushMatrix();
   {
    glRotatef((GLfloat)Luna, 0.0, 1.0, 0.0);
    glTranslatef(-1.0, 0.0, -20.0);
    glColor3f(1.0f, 1.0f, 0.0);
    glutSolidSphere(2, 10, 10);
   }
   glPopMatrix();

  }
  glPopMatrix();

  // xy 시계방향 구
  glPushMatrix();
  {
   glRotatef(45.0, 0.0, 0.0, 1.0);
   glRotatef((GLfloat)planet2, 0.0, 1.0, 0.0);
   glTranslatef(30.0, 0.0, 75.0);
   glRotatef((GLfloat)Luna, 0.0, 1.0, 0.0);
   glColor3f(0.5f, 1.0f, 0.8f);
   glutSolidSphere(5, 100, 100);

   // 달 궤도
   glPushMatrix();
   {
    glColor3f(0.0, 0.0, 0.0);
    glBegin(GL_LINE_LOOP);
    for (int degree = 0; degree < 360; degree += 1)
    {
     float radian = (float)degree*3.141592f / 180.f;
     glVertex3f(sin(radian) * 20,0.0, cos(radian) * 20);
    }
    glEnd();
   }
   glPopMatrix();

   // 달
   glPushMatrix();
   {
    glRotatef((GLfloat)Luna, 0.0, 1.0, 0.0);
    glTranslatef(-1.0, 0.0, -20.0);
    glColor3f(1.0f, 1.0f, 0.0);
    glutSolidSphere(2, 10, 10);
   }
   glPopMatrix();
  }
  glPopMatrix();

  // xy 반시계방향 구
  glPushMatrix();
  {
   glRotatef(-45.0, 0.0, 0.0, 1.0);
   glRotatef((GLfloat)planet3, 0.0, 1.0, 0.0);
   glTranslatef(30.0, 0.0, 75.0);
   glRotatef((GLfloat)Luna, 0.0, 1.0, 0.0);
   glColor3f(0.0f, 1.0f, 0.0f);
   glutSolidSphere(5, 100, 100);

   // 달 궤도
   glPushMatrix();
   {
    glColor3f(0.0, 0.0, 0.0);
    glBegin(GL_LINE_LOOP);
    for (int degree = 0; degree < 360; degree += 1)
    {

     float radian = (float)degree*3.141592f / 180.f;
     glVertex3f(sin(radian) * 20, 0.0, cos(radian) * 20);
    }
    glEnd();
   }
   glPopMatrix();
   // 달
   glPushMatrix();
   {
    glRotatef((GLfloat)Luna, 0.0, 1.0, 0.0);
    glTranslatef(-1.0, 0.0, -20.0);
    glColor3f(1.0f, 1.0f, 0.0);
    glutSolidSphere(2, 10, 10);
   }
   glPopMatrix();
  }
  glPopMatrix();
 }

 glutSwapBuffers();
}

​

void MenuFunc(int button)
{
 switch (button)
 {
 case 1:
  wire = false;
  break;
 case 2:
  wire = true;
  break;
 case 3:
  exit(1);
  break;
 default:
  break;
 }
 glutPostRedisplay();
}

​

void MyTimer(int value)
{
 planet1 = (planet1 + 1) % 360;
 planet2 = (planet2 + 2) % 360;
 planet3 = (planet3 + 3) % 360;
 Luna = (Luna + 1) % 360;
 glutPostRedisplay();
 glutTimerFunc(fps, MyTimer, 1);
} 
반응형
Comments