LoginSignup
1
1

More than 3 years have passed since last update.

【OpenGL】エンジンを使わないゲーム開発 -GLUTによるアニメーション-

Last updated at Posted at 2019-12-15

緒論

前回描画した図形にアニメーションをつけることを目的とする.

理論

1. idle関数

これは何もしてないときに呼ばれる関数.暇になるたびに呼び出される.

    void glutIdleFunc(void (*func)(void));

2. 再描画関数

再描画をさせる関数.これが呼ばれるとglutDisplayFunc()で指定されている描画関数が実行される.

    void glutPostRedisplay(void)

3. 回転させる関数

描画したものを指定した軸方向にangle度回転する.

    void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);

方法

idle関数を作ってglutPostRedisplay()を入れる.こうすることで,暇なときに再描画するという処理が行われる.

void idle()
{
    glutPostRedisplay();
}

int main(int argc, char *argv[])
{
    // -省略-
    glutIdleFunc(idle);
    // -省略-
}

よって呼び出される関数glutDisplayFunc()の中身に回転するプログラムを書けばアニメーションが行われるということである

void Display()
{
    // (GLfloat angle, GLfloat x, GLfloat y, GLfloat z) 指定した軸方向にangle度回転する関数
    glRotatef(1, 1, 1, 0);
    // -省略-
}

結果

今回,ディスプレイの表示モードをGLUT_RGBAからGLUT_DOUBLEに変更した.ダブルバッファリングというもので,表示のちらつきを抑えるためのものらしい.
詳しくは9.2 ダブルバッファリングを参照.

なぜか私はダブルバッファリングをしなくても画面がチラつかず,表示モードを変えても特に実行結果は変わらなかったが,とりあえず,ダブルバッファリングを使用するプログラムに変更した.

Dec-15-2019 11-19-11.gif

main.cpp
main.cpp
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include "polygon.hpp"
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

// この中に描画したいものを入れる
void Display()
{
    // (GLfloat angle, GLfloat x, GLfloat y, GLfloat z) 指定した軸方向にangle度回転する関数
    glRotatef(1, 1, 1, 0);
    // (GLbitfield mask)ウィンドウを塗りつぶす maskは塗りつぶすためのバッファを指定する
    glClear(GL_COLOR_BUFFER_BIT);

    // ▼図形を描くためのプログラム▼
    // (GLdouble r, GLdouble g, GLdouble b)これから描画するものの色を指定する
    glColor3d(1.0, 0.0, 0.0);
    // (GLnum mode)modeに図形タイプを入力 LINE_LOOPは折れ線を描く
    glBegin(GL_LINE_LOOP);
    // (GLdouble x, GLdouble y)二次元の座標値を設定する
    Polygon(5);
    // (void)Begin~Endまでに図形の各頂点の座標値を指定する
    glEnd();
    // ▲図形を描くためのプログラム▲

    // (void)まだ実行されていないOpenGLの命令を実行
    glutSwapBuffers();
}

// 初期化処理を行う関数
void init(void)
{
    // (GLclampf R, GLclampf G, GLclampf B, GLclampf A)glclearでウィンドウを塗りつぶす際の色の指定
    glClearColor(0.0, 0.0, 0.0, 1.0);
}

void idle()
{
    // 再描画の関数 glutDisplayFunc()が実行される.
    glutPostRedisplay();
}

int main(int argc, char *argv[])
{
    // (int *argcp, char **argv)GLUTとOpenGL環境の初期化
    glutInit(&argc, argv);
    // (unsigned int mode)ディスプレイの表示モードを設定 GLUT_RGBAを指定すると色の指定を三原色で行える
    glutInitDisplayMode(GLUT_DOUBLE);
    // (char *name)ウィンドウを開く関数
    glutCreateWindow("Title");
    // (void (*func)(void))ウィンドウが開かれたり再描画の際に実行
    glutDisplayFunc(Display);
    init();
    // (void (*func)(void))暇なときに呼ばれる関数.暇になるたび実行
    glutIdleFunc(idle);
    // (void)無限ループの関数,イベント待ち状態
    glutMainLoop();
    return 0;
}

ここまで制作して思ったのが,暇になるたびidle関数が呼び出され,Display関数内のrotate関数によって図形が1度ずつフレーム単位で回転していると思うのだが,再描画をしたら回転情報はリセットされないのだろうか.前の回転状態がなんで残っているのか不思議である.

結論

  • アニメーションができた!
  • 描画図形の回転情報は再描画しても残り続ける.
1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1