#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <math.h>
#define PI_OVER_180 0.034906585 / 2   // /180

#define W 20                       /* 地面の幅の2分の1 */
#define D 30                        /* 地面の長さの2分の1 */


/*
 * 地面を描く
 */
void myGround(double height)
{
  static GLfloat ground[][4] = {
    { 0.9, 0.0, 0.9, 1.0 },
    { 0.0, 0.9, 0.9, 1.0 }
  };
  
  int i, j;
  
  glBegin(GL_QUADS);
  glNormal3d(0.0, 1.0, 0.0);
  for (j = -D; j < D; ++j) {
    for (i = -W; i < W; ++i) {
      glMaterialfv(GL_FRONT, GL_DIFFUSE, ground[(i + j) & 1]);
      glVertex3d((GLdouble)i, height, (GLdouble)j);
      glVertex3d((GLdouble)i, height, (GLdouble)(j + 1));
      glVertex3d((GLdouble)(i + 1), height, (GLdouble)(j + 1));
      glVertex3d((GLdouble)(i + 1), height, (GLdouble)j);
    }
  }
  glEnd();
}

void idle(void)
{
  glutPostRedisplay();
}

/*
 * 画面表示
 */
void display(void)
{
  static GLfloat lightpos[] = { 3.0, 4.0, 5.0, 1.0 }; /*  光源の位置 */
  static GLfloat color[] = { 0.5, 1.0, 1.0, 1.0 };   /* やかんの色 */
  static GLdouble px = 0.0 ,pz = 0.0;                 /* やかんの位置 */
  static GLdouble r = 0.0;                            /* やかんの方向 */
  pz = 4 * cos((GLfloat)glutGet(GLUT_ELAPSED_TIME) / 150); 
  px = 4 * sin((GLfloat)glutGet(GLUT_ELAPSED_TIME) / 150);
  r = 0.16 * (GLfloat)glutGet(GLUT_ELAPSED_TIME);
  /* 画面クリア */
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
  /* モデルビュー変換行列の初期化 */
  glLoadIdentity();
  
  /* 光源の位置を設定 */
  glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  
  /* 視点の移動(物体の方を奥に移す) */
  glTranslated(0.0, 0.0, -25.0);
  glRotated(30.0, 1.0, 0.0, 0.0);
  
  /* シーンの描画 */
  myGround(0.0);
  glPushMatrix();
  glRotated(r - 90.0, 0.0, 1.0, 0.0);
  glTranslated(px, 1.0, pz);
  glMaterialfv(GL_FRONT, GL_DIFFUSE, color);
  glutSolidTeapot(1.0);
  glPopMatrix();

  glutSwapBuffers();
}

void resize(int w, int h)
{
  /* ウィンドウ全体をビューポートにする */
  glViewport(0, 0, w, h);

  /* 透視変換行列の指定 */
  glMatrixMode(GL_PROJECTION);
  
  /*  透視変換行列の初期化 */
  glLoadIdentity();
  gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0);
  
  /* モデルビュー変換行列の指定 */
  glMatrixMode(GL_MODELVIEW);
}

void init(void)
{
  /* 初期設定 */
  glClearColor(1.0, 1.0, 1.0, 0.0);
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_CULL_FACE);
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
}

int main(int argc, char *argv[])
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
  glutCreateWindow(argv[0]);
  glutDisplayFunc(display);
  glutReshapeFunc(resize);
  init();
  glutIdleFunc(idle);
  glutMainLoop();
  return 0;
}

戻る