シダ(C、OpenGL、glut)

 

Windows、C、OpenGL、glutで

シダを描画しました

BASICでは描画過程を見ることが

出来ましたが

Cでは一瞬で描画されるので

リアルタイムで動かすことが

出来ます

 

'\','/'キーで前進後退

カーソルキーで方向転換

'p'で四角の表示非表示切り替え

'r'で逆回転

enterキー視点のリセット

です

 

leaf.cをコンパイルには

glut.h, glut32.lib, glut32.dll

が必要です

(昔ダウンロードしたので現在のリンクは

不明です

freeGlutなどが代わりにあるそうです)

glutはv-syncがオンにならなかったので

Sleepを入れてあります

(コメントを外すと時間待ちします)

 

Win32アプリでコンパイルすると

consoleウインドウは開きません

のでprintfは使えませんが

ウインドウが1個なので

見やすくなります

 

Consoleアプリでコンパイルすると

consoleウインドウが開きますので

printfが使えますがウインドウが

2個になり見た目が悪くなります

 

glutを使わずに作ったバージョンの

leaf.exeも同包しました

(こちらはv-sync同期です

また、glut32.dllは必要ありません)

 

etc21213.zip(leaf.c, leaf.exe)は

以下のリンクからダウンロードできます

VL-BASIC(N88-BASIC互換?)ホームページ

Readme.txtを読んで遊んで下さい

 

 

 

leaf.c

~.cはコメント以外のプログラムコードは自由に参考にして
使用して下さい
コメントを使用するときはULprojectの名を入れて下さい
 

/*                                                               leaf.c
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
シダ

Copyright(C) 2019-2020 ULpriject
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
INCLUDE FILE(s)
───────────────────────────────────*/
#ifdef WIN32
#include <windows.h>
#endif
#include "glut.h"
                                                                      /*
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
MACRO(s)
───────────────────────────────────*/
#ifdef WIN32
#define state(key)    (GetAsyncKeyState(key) < 0)    /* 現在(& 0x8000) */
#define sleep(ms)    Sleep(ms)    
#else
#define state(key)    0
#define sleep(ms)    
#endif
                                                                      /*
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CONSTANT(s)
───────────────────────────────────*/
#ifdef WIN32
#define KEY_U    VK_UP
#define KEY_D    VK_DOWN
#define KEY_L    VK_LEFT
#define KEY_R    VK_RIGHT
#define KEY_B    VK_OEM_2        /* /? */
#define KEY_F    VK_OEM_102        /* \_ */
#else
#define KEY_U    0
#define KEY_D    0
#define KEY_L    0
#define KEY_R    0
#define KEY_B    0        /* /? */
#define KEY_F    0        /* \_ */
#endif
                                                                      /*
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
WINDOWS FUNCTION(s)
───────────────────────────────────*/
#ifdef _WINDOWS    /* #ifndef _CONSOLE */
void main(int argc, char** argv);
int WINAPI WinMain(HINSTANCE inst, HINSTANCE n, LPSTR arg, int show)
{
    int    argc = 1;
    char** argv = &arg;

    main(argc, argv);
    return 0;
}
#endif
                                                                      /*
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PRIVATE VARIABLE(s)
───────────────────────────────────*/
static double leaf_d =  0.0;
static double leaf_s = -1.0;
static int    leaf_p =  1;
                                                                      /*
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PRIVATE FUNCTION(s)
───────────────────────────────────*/
static
void display(void)
{
    glutSwapBuffers();
}
                                                                      /*
───────────────────────────────────*/
static
void reshape(int w, int h)
{
    glViewport(0, 0, w, h);
}
                                                                      /*
───────────────────────────────────*/
static
void leaf(double size, int times)
{
    double x, y, r;
    int    i;

    x = y = 0.0;
    for (i = 0; i < times; i++)
    {
        glVertex2d(x * size, y * size);    /* 点 */
        r = ((double)rand()) / (1.0 + (double)RAND_MAX);
        if      (r < 0.01)
        {
            r = 0;
            y = y * 0.16;
        }
        else if (r < 0.01 + 0.07)
        {
            r = x * 0.20 - y * 0.26;
            y = x * 0.23 + y * 0.22 + 1.60;
        }
        else if (r < 0.01 + 0.07 + 0.07)
        {
            r = y * 0.28 - x * 0.15;
            y = x * 0.26 + y * 0.24 + 0.44;
        }
        else
        {
            r = x * 0.85 + y * 0.04;
            y = y * 0.85 - x * 0.04 + 1.60;
        }
        x = r;
    }
}
                                                                      /*
───────────────────────────────────*/
static
void keyboard(unsigned char key, int x, int y)
{
    switch (key)
    {
    case 'p': leaf_p = !leaf_p; break;
    case 'r': leaf_s = -leaf_s; break;
    case ' ': glRotated(180, 0.0, 1.0, 0.0); break;
    case 13 : glLoadIdentity(); break;
    }
}
                                                                      /*
───────────────────────────────────*/
static
void move(void)
{
    double d = 0.5;
    double z = 5.0;

    if (state(KEY_U)) glRotated( d, 1.0, 0.0, 0.0);
    if (state(KEY_D)) glRotated(-d, 1.0, 0.0, 0.0);
    if (state(KEY_L)) glRotated(-d, 0.0, 1.0, 0.0);
    if (state(KEY_R)) glRotated( d, 0.0, 1.0, 0.0);
    if (state(KEY_B)) glTranslated(0.0, 0.0, -z  );
    if (state(KEY_F)) glTranslated(0.0, 0.0,  z  );
}
                                                                      /*
───────────────────────────────────*/
static
void idle(void)
{
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);    /* r,g,b,a */
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    move();

    /* 四角形 */
    if (leaf_p)
    {
        glPushMatrix();
        glTranslated(0.0, 0.0, -1080);
        glColor3d(0.8, 0.5, 0.0);
        glBegin(GL_QUADS);
            glColor3d(0.8, 0.5, 0.0);
            glVertex3d(-320, -180,   0);
            glVertex3d(-320,  180, -64);
            glVertex3d(   0,  180, -64);
            glVertex3d(   0, -180,   0);
        glEnd();
        glPopMatrix();
    }

    /* シダ */
    glPushMatrix();
    glTranslated(0.0, -180, -1080);
    glRotated(leaf_d, 0.0, 1.0, 0.0);
    leaf_d += leaf_s;
    glBegin(GL_POINTS);                /* 点 */
        glColor3d(0.0, 1.0, 0.0);
        leaf(40, 10000);
    glEnd();
    glPopMatrix();

    glFlush();            /* 上記glコマンドをすへて実行 */
    glutSwapBuffers();    /* Duble buffer(表示面と描画面)の切替 */
//    sleep(15);            /* 時間待ち(1000/60=16.6...ms */
}
                                                                      /*
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
FUNCTION(s)
───────────────────────────────────*/
void main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitWindowSize(704, 396);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Leaf (ULproject)");

    glEnable(GL_DEPTH_TEST);        /* Depth buffer on */
    glMatrixMode(GL_PROJECTION);    /* 行列モード変更  */
    glLoadIdentity();                /* 単位行列        */
    /*          X0   X1    Y0   Y1    Z      Far */
    glFrustum(-320, 320, -180, 180, 720, 1000000);
    glMatrixMode(GL_MODELVIEW);        /* 行列モード変更  */
    glLoadIdentity();                /* 単位行列        */

    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    glutIdleFunc(idle);                /* ここに処理を書く */

    glutMainLoop();                    /* 帰ってこない     */
}