読者です 読者をやめる 読者になる 読者になる

個人的自由ノート

ふと自分が気になった事を書いてます

OpenGLを学習

3回目です。

#include <GL/glut.h>

GLdouble vertex[][3] = {
  { 0.0, 0.0, 0.0 },
  { 1.0, 0.0, 0.0 },
  { 1.0, 1.0, 0.0 },
  { 0.0, 1.0, 0.0 },
  { 0.0, 0.0, 1.0 },
  { 1.0, 0.0, 1.0 },
  { 1.0, 1.0, 1.0 },
  { 0.0, 1.0, 1.0 }
};

int edge[][2] = {
  { 0, 1 },
  { 1, 2 },
  { 2, 3 },
  { 3, 0 },
  { 4, 5 },
  { 5, 6 },
  { 6, 7 },
  { 7, 4 },
  { 0, 4 },
  { 1, 5 },
  { 2, 6 },
  { 3, 7 }
};

void display(void){
    int i;

    glClear(GL_COLOR_BUFFER_BIT);

    glColor3d(0.0, 0.0, 0.0);
    glBegin(GL_LINES);
    for(i = 0; i < 12; ++i){
        glVertex3dv(vertex[edge[i][0]]);
        glVertex3dv(vertex[edge[i][1]]);
    }
    glEnd();
    glFlush();
}

void resize(int w, int h){
    glViewport(0, 0, w, h);

    glLoadIdentity();
    gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0);
    glTranslated(0.0, 0.0, -5.0);
}

void init(void){
    glClearColor(1.0, 1.0, 1.0, 1.0);
}

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

gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) 変換行列に透視変換の行列を乗じます. 最初の引数 fovy はカメラの画角であり, 度で表します. これが大きいほどワイドレンズ (透視が強くなり, 絵が小さくなります) になり, 小さいほど望遠レンズになります. 二つ目の引数 aspect は画面のアスペクト比 (縦横比) であり, 1 であればビューポートに表示される図形の x 方向と y 方向のスケールが等しくなります. 三つ目の引数 zNear と四つ目の引数 zFar は表示を行う奥行き方向の範囲で, zNear は手前 (前方面), zFar は後方 (後方面) の位置を示します. この間にある図形が描画されます.

glTranslated(GLdouble x, GLdouble y, GLdouble z) 変換行列に平行移動の行列を乗じます. 引数はいずれも GLdouble 型 (double と等価) で, 三つの引数 x, y, z には現在の位置からの相対的な移動量を指定します. 引数が float 型なら glTranslatef() を使います.

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-11-13-19-36-52

#include <GL/glut.h>

GLdouble vertex[][3] = {
  { 0.0, 0.0, 0.0 },
  { 1.0, 0.0, 0.0 },
  { 1.0, 1.0, 0.0 },
  { 0.0, 1.0, 0.0 },
  { 0.0, 0.0, 1.0 },
  { 1.0, 0.0, 1.0 },
  { 1.0, 1.0, 1.0 },
  { 0.0, 1.0, 1.0 }
};

int edge[][2] = {
  { 0, 1 },
  { 1, 2 },
  { 2, 3 },
  { 3, 0 },
  { 4, 5 },
  { 5, 6 },
  { 6, 7 },
  { 7, 4 },
  { 0, 4 },
  { 1, 5 },
  { 2, 6 },
  { 3, 7 }
};

void display(void){
    int i;

    glClear(GL_COLOR_BUFFER_BIT);

    glColor3d(0.0, 0.0, 0.0);
    glBegin(GL_LINES);
    for(i = 0; i < 12; ++i){
        glVertex3dv(vertex[edge[i][0]]);
        glVertex3dv(vertex[edge[i][1]]);
    }
    glEnd();
    glFlush();
}

void resize(int w, int h){
    glViewport(0, 0, w, h);

    glLoadIdentity();
    gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0);
    gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}

void init(void){
    glClearColor(1.0, 1.0, 1.0, 1.0);
}

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

void gluLookAt(GLdouble ex, GLdouble ey, GLdouble ez, GLdouble cx, GLdouble cy, GLdouble cz, GLdouble ux, GLdouble uy, GLdouble uz) この最初の三つの引数 ex, ey, ez は視点の位置, 次の三つの引数 cx, cy, cz は目標の位置, 最後の三つの引数 ux, uy, uz は, ウィンドウに表示される画像の「上」の方向を示すベクトルです.

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-11-13-19-42-29

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

GLdouble vertex[][3] = {
  { 0.0, 0.0, 0.0 },
  { 1.0, 0.0, 0.0 },
  { 1.0, 1.0, 0.0 },
  { 0.0, 1.0, 0.0 },
  { 0.0, 0.0, 1.0 },
  { 1.0, 0.0, 1.0 },
  { 1.0, 1.0, 1.0 },
  { 0.0, 1.0, 1.0 }
};

int edge[][2] = {
  { 0, 1 },
  { 1, 2 },
  { 2, 3 },
  { 3, 0 },
  { 4, 5 },
  { 5, 6 },
  { 6, 7 },
  { 7, 4 },
  { 0, 4 },
  { 1, 5 },
  { 2, 6 },
  { 3, 7 }
};

void idle(void){
  glutPostRedisplay();
}

void display(void){
    int i;
  static int r = 0;

    glClear(GL_COLOR_BUFFER_BIT);

  glLoadIdentity();

  gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

  glRotated((double)r, 0.0, 1.0, 0.0);

    glColor3d(0.0, 0.0, 0.0);
    glBegin(GL_LINES);
    for(i = 0; i < 12; ++i){         glVertex3dv(vertex[edge[i][0]]);       glVertex3dv(vertex[edge[i][1]]);   }   glEnd();    glFlush();   if(++r >= 360) r = 0;
}

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 mouse(int button, int state, int x, int y){
  switch(button){
    case GLUT_LEFT_BUTTON:
      if(state == GLUT_DOWN){
        glutIdleFunc(idle);
      } else {
        glutIdleFunc(0);
      }
      break;
    case GLUT_RIGHT_BUTTON:
      if(state == GLUT_DOWN){
        glutPostRedisplay();
      }
      break;
    default:
      break;
  }
}

void keyboard(unsigned char key, int x, int y){
  switch(key){
    case 'q':
    case 'Q':
    case '\033':
      exit(0);
    default:
      break;
  }
}

void init(void){
    glClearColor(1.0, 1.0, 1.0, 1.0);
}

int main(int argc, char** argv){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA);
    glutCreateWindow(argv[0]);
    glutDisplayFunc(display);
    glutReshapeFunc(resize);
  glutMouseFunc(mouse);
  glutKeyboardFunc(keyboard);
    init();
    glutMainLoop();
    return 0;
}

void glutPostRedisplay(void) 再描画イベントを発生させます. このイベントの発生が発生すると, glutDisplayFunc() で指定されている描画関数が実行されます. なお, 再描画が開始されるまでの間にこのイベントが複数回発生しても, この描画関数は一度だけ実行されます.

void glutIdleFunc(void (*func)(void)) 引数 func には, このプログラムが暇な (何もすることがない) ときに実行する関数のポインタを指定します. 引数の関数はプログラムが「暇になる」たびに繰り返し実行されます. この関数を指定すると, プログラムが止まっているように見えてもコンピュータの負荷は増大します. したがって glutIdleFunc() による関数の指定は必要になった時点で行い, 不要になれば glutIdleFunc() の引数に 0 または NULL を指定して関数の指定を解除してやる必要があります.

void glMatrixMode(GLenum mode) 設定する変換行列を指定します. 引数 mode が GL_MODELVIEW ならモデルビュー変換行列, GL_PROJECTION なら透視変換行列を指定します.

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-11-13-19-55-19