ゲームが作れるようになるまでがんばる日記

ゲーム制作のことを中心にゲームに関することを書いています

ダブルバッファ化

ダブルバッファで描画するように改良。ついでにマウス関連の関数も追加。

#include <GL/glut.h>

// ウィンドウが描画されるとき
void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    // ここでラインやポリゴンの描画

    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);
    gluLookAt(10.0, 12.0, 14.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    glMatrixMode(GL_MODELVIEW);
}

// キーボードが押されたとき
void keyboard(unsigned char key, int x, int y)
{
    switch (key)
    {
    case 'q':
    case 'Q':
    case '\033':  /* '\033' は ESC の ASCII コード */
        exit(0);
    default:
        break;
    }
}

// マウスのボタンが押されたとき
void mouse(int button, int state, int x, int y)
{
    switch (button)
    {
    case GLUT_LEFT_BUTTON:
        break;
    case GLUT_MIDDLE_BUTTON:
        break;
    case GLUT_RIGHT_BUTTON:
        break;
    default:
        break;
    }
}

// マウスがドラッグされたとき
void motion(int x, int y)
{
}

void init(void)
{
    glClearColor(0.0, 0.0, 0.0, 1.0); // 画面のクリアカラー
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
}

int main(int argc, char *argv[])
{
    glutInitWindowSize(800, 600); // Windowサイズを指定
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow(argv[0]);
    glutDisplayFunc(display);
    glutReshapeFunc(resize);
    glutKeyboardFunc(keyboard);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    init();
    glutMainLoop();
    return 0;
}

描画は必要なときのみされるので、座標の更新などを行ったら glutPostRedisplay() を呼んで描画関数が呼ばれるようにしなくてはならない。
自動的に描画されるようにするには glutIdleFunc() を使う方法もある。

void idle()
{
    glutPostRedisplay()
}

glutIdleFunc(idle); // idle関数の登録
glutIdleFunc(0); // idle関数の解除

プログラムがIDLE状態のときにglutIdleFunc()で登録された関数が呼ばれるようになる。ただし、負荷が上がってしまうので必要のないときは解除しておくとよい。
あるいはタイマーで一定間隔でglutPostRedisplay()を呼ぶようにしてもいいかもしれない。