EQQ.jp

Index


 

MinGW 3Dグラフィックス

 

3Dグラフィックス

MinGW で、OpenGL(GLUT) を利用した3Dグラフィックスプログラムがコンパイル実行できるように設定し、3次元に拡張したライフゲームを実行します。

 

GLUT のインストール

MinGW をインストールすると、OpenGL, GLU はインストールされているようなので、GLUT を追加でインストールします。

インターネット上の、http://web.cs.wpi.edu/~gogo/courses/mingw/ から、Installing GLUT の “this GLUT archive” をクリックして、”winglut.zip” をダウンロードします。ZIP ファイルを解凍して、以下のファイルを MinGW のインストールディレクトリにコピーします。

ここで、libglut32win.a という名前のライブラリファイルは、libglut32.a という名前に変更しました。glut32.dll は実行パスが通っているディレクトリにコピーしてください。

 

ライフゲームプログラム

GLUT を利用した3次元出力をする3次元ライフゲームのソースを以下に示します。

#include        <stdio.h>
#include        <windows.h>
#include        <GL/glut.h>     // cc life3g.c -lglut32 -lopengl32 -lglu32

#define MAXSTEP 500     // Step
#define BMX     24      // Max x size of board
#define BMY     24      // Max y size of board
#define BMZ     24      // Max z size of board

int     b[BMX+2][BMY+2][BMZ+2]; // Board Empty:0 Marked:3

GLdouble vertexgl[][3] = {
        { 0.0, 0.0, 0.0},
        { 0.8, 0.0, 0.0},
        { 0.8, 0.8, 0.0},
        { 0.0, 0.8, 0.0},
        { 0.0, 0.0, 0.8},
        { 0.8, 0.0, 0.8},
        { 0.8, 0.8, 0.8},
        { 0.0, 0.8, 0.8}
};

GLdouble colorgl[][3] = {
        {0.8, 0.2, 0.2},
        {0.2, 0.8, 0.2},
        {0.2, 0.2, 0.8},
        {0.7, 0.7, 0.0},
        {0.7, 0.0, 0.7},
        {0.0, 0.7, 0.7}
};

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

void cubegl() {
        int i;
        int j;

        glBegin(GL_QUADS);
        for(j = 0; j < 6; ++ j) {
                glColor3dv(colorgl[j]);
                for(i = 0; i < 4; ++ i) {
                        glVertex3dv(vertexgl[facegl[j][i]]);
                }
        }
        glEnd();
}

void displaygl() {
        int x;
        int y;
        int z;
        static float ry = 0.0;
        static float rx = 0.0;

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glPushMatrix();

        glRotatef(ry, 0.0, 1.0, 0.0);
        glRotatef(rx, 1.0, 0.0, 0.0);
        glTranslated(-0.5*BMX, -0.5*BMY, -0.5*BMZ);

        for(z = 1; z <= BMZ; z++) {
                for(y = 1; y <= BMY; y++) {
                        for(x = 1; x <= BMX; x++) {
                                if(b[x][y][z] != 0) {
                                        glPushMatrix();
                                        glTranslated(1.0*x, 1.0*y, 1.0*z);
                                        cubegl();
                                        glPopMatrix();
                                }
                        }
                }
        }

        glPopMatrix();

        glutSwapBuffers();

        ry += 2.0;
        rx += 1.5;
        if(ry >= 360.0) ry -= 360.0;
        if(rx >= 360.0) rx -= 360.0;
}

void keyboardgl(unsigned char key, int x, int y) {
        switch(key) {
        case '\033':            // ESC key
                exit(0);
                break;
        default:
                break;
        }
}

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

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(60.0, (double)w / (double)h, 1.0, 100.0);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(BMX*1.2, BMY*1.2, BMZ*1.2, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}

void inputboard() {
        int     x;
        int     y;
        int     z;

        for(z = 0; z < BMZ+2; z++) {
                for(y = 0; y < BMY+2; y++) {
                        for(x = 0; x < BMX+2; x++) {
                                b[x][y][z] = 0;
                        }
                }
        }

        b[10][14][10] = 3;
        b[10][15][10] = 3;
        b[10][16][10] = 3;
        b[11][14][10] = 3;
        b[9][15][10] = 3;
}

int countalive(int x, int y, int z) {
        int cal = 0;

//      if(b[x-1][y-1][z-1] > 1) cal ++;
        if(b[x-1][y][z-1] > 1) cal ++;
//      if(b[x-1][y+1][z-1] > 1) cal ++;
        if(b[x][y-1][z-1] > 1) cal ++;
        if(b[x][y][z-1] > 1) cal ++;
        if(b[x][y+1][z-1] > 1) cal ++;
//      if(b[x+1][y-1][z-1] > 1) cal ++;
        if(b[x+1][y][z-1] > 1) cal ++;
//      if(b[x+1][y+1][z-1] > 1) cal ++;

        if(b[x-1][y-1][z] > 1) cal ++;
        if(b[x-1][y][z] > 1) cal ++;
        if(b[x-1][y+1][z] > 1) cal ++;
        if(b[x][y-1][z] > 1) cal ++;
        if(b[x][y+1][z] > 1) cal ++;
        if(b[x+1][y-1][z] > 1) cal ++;
        if(b[x+1][y][z] > 1) cal ++;
        if(b[x+1][y+1][z] > 1) cal ++;

//      if(b[x-1][y-1][z+1] > 1) cal ++;
        if(b[x-1][y][z+1] > 1) cal ++;
//      if(b[x-1][y+1][z+1] > 1) cal ++;
        if(b[x][y-1][z+1] > 1) cal ++;
        if(b[x][y][z+1] > 1) cal ++;
        if(b[x][y+1][z+1] > 1) cal ++;
//      if(b[x+1][y-1][z+1] > 1) cal ++;
        if(b[x+1][y][z+1] > 1) cal ++;
//      if(b[x+1][y+1][z+1] > 1) cal ++;

        return cal;
}

void nextstep() {
        int x;
        int y;
        int z;
        int cal;

        for(z = 1; z <= BMZ; z++) {
                for(y = 1; y <= BMY; y++) {
                        for(x = 1; x <= BMX; x++) {
                                cal = countalive(x, y, z);
                                if(b[x][y][z] == 0) {
                                        if(cal == 3) b[x][y][z] = 1;
                                } else if(b[x][y][z] == 3) {
                                        if(cal < 2) b[x][y][z] = 2;
                                        if(cal > 3) b[x][y][z] = 2;
                                } else {
                                        printf("Unknown code of board[%d][%d][%d]\n", x, y, z);
                                }
                        }
                }
        }
        for(z = 1; z <= BMZ; z++) {
                for(y = 1; y <= BMY; y++) {
                        for(x = 1; x <= BMX; x++) {
                                if(b[x][y][z] == 1) b[x][y][z] = 3;
                                if(b[x][y][z] == 2) b[x][y][z] = 0;
                        }
                }
        }
}

void idlegl() {
        glutPostRedisplay();
        nextstep();
}

void initgl(int argc, char* argv[]) {
        glutInitWindowSize(640, 480);
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
        glutCreateWindow(argv[0]);
        glutDisplayFunc(displaygl);
        glutReshapeFunc(resizegl);
        glutIdleFunc(idlegl);
        glutKeyboardFunc(keyboardgl);

        glClearColor(0.0, 0.0, 0.0, 1.0);
        glEnable(GL_CULL_FACE);
        glCullFace(GL_FRONT);
}

int main(int argc, char* argv[]) {
        inputboard();
        initgl(argc, argv);
        glutMainLoop();
        return 0;
}

 

 

ソースプログラムを life3g.c とした場合、コンパイルは以下のように実行してください。

> cc life3g.c -lglut32 -lopengl32 -lglu32

 

 

実行してみると、単純に3次元に拡張しただけでは、いまひとつ結果が面白くない感じがします。

 

MinGW LifeGame 3D Graphics