シダ(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)は
以下のリンクからダウンロードできます
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(); /* 帰ってこない */
}