/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- init
- scene
- display
- resize
- idle
- mouse
- motion
- keyboard
<?php
/*
* http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20060227
*/
require_once 'particle.php';
require_once 'screenshot.php';
/*
** 光源
*/
$lightpos = array( 0.0, 0.0, 1.0, 0.0 ); /* 位置 */
$lightcol = array( 1.0, 1.0, 1.0, 1.0 ); /* 直接光強度 */
$lightamb = array( 0.1, 0.1, 0.1, 1.0 ); /* 環境光強度 */
/*
** パーティクル
*/
//define('MAX_PARTICLES', 800);
define('MAX_PARTICLES', 200);
$psize = 0;
$distance = array( 0.0, 0.0, 1.0 );
/*
** 地面の高さ
*/
define('HEIGHT', -1.0);
/*
** 初期化
*/
function init()
{
global $distance;
/* 初期設定 */
glClearColor(0.3, 0.3, 1.0, 0.0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
/* 陰影付けを無効にする */
// glDisable(GL_LIGHTING);
/* 地面の高さ */
particle::height(HEIGHT);
//
$lit_amb = array(1.0, 1.0, 1.0, 0.0); /* 環境光の強さ */
$lit_dif = array(1.0, 1.0, 1.0, 0.0); /* 拡散光の強さ */
$lit_spc = array(1.0, 1.0, 1.0, 0.0); /* 鏡面反射光の強さ */
$lit_pos = array(-5.0, 5.0, -8.0, 1.0); /* 光源の位置 */
glLightfv(GL_LIGHT0, GL_AMBIENT, $lit_amb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, $lit_dif);
glLightfv(GL_LIGHT0, GL_SPECULAR, $lit_spc);
glLightfv(GL_LIGHT0, GL_POSITION, $lit_pos);
/* ライトを有効にする */
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
// glBlendFunc(GL_ONE, GL_ONE);
// glBlendFunc(GL_ONE, GL_SRC_COLOR);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
/*
** シーンの描画
*/
function scene()
{
global $particles;
global $psize;
/* パーティクルを生成する */
if (count($particles) >= MAX_PARTICLES) {
array_pop($particles);
}
$particles []= new particle();
/* アルファテストを有効にする */
glEnable(GL_ALPHA_TEST);
/* パーティクルを描く */
glEnable(GL_BLEND);
foreach ($particles as $idx => $ip) {
$div_r = 1 - 1/($idx % 4 + 1)/1.5;
$div_g = 1 - 1/($idx % 3 + 1)/1.5;
$div_b = 1 - 1/($idx % 2 + 1)/1.5;
$position = $ip->getPosition();
glPushMatrix();
$color = array(1.0 * $div_r, 1.0 * $div_g, 1.0 * $div_b, 1.0);
glMaterialfv(GL_FRONT, GL_DIFFUSE, $color);
glTranslatef($position[0], $position[1], $position[2]);
glutSolidSphere(0.08, 16, 10);
glPopMatrix();
$ip->update();
}
glDisable(GL_BLEND);
/* アルファテストを無効にする */
glDisable(GL_ALPHA_TEST);
}
/****************************
** GLUT のコールバック関数 **
****************************/
require_once 'trackball.php';
function display()
{
global $lightpos;
/* モデルビュー変換行列の初期化 */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* 光源の位置を設定 */
glLightfv(GL_LIGHT0, GL_POSITION, $lightpos);
/* 視点の移動(物体の方を奥に移動)*/
glTranslated(0.0, 0.0, -3.0);
/* トラックボール処理による回転 */
glMultMatrixd(trackball::Rotation());
/* 画面クリア */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* シーンの描画 */
scene();
/* ダブルバッファリング */
glutSwapBuffers();
//
static $sc_id = 0;
if (($sc_id % 16) == 0) {
screenshot(sprintf("output%04d.png", $sc_id));
}
$sc_id++;
}
function resize($w, $h)
{
global $psize;
/* 点の大きさを設定する */
$psize = $w * 0.1;
/* トラックボールする範囲 */
trackball::Region($w, $h);
/* ウィンドウ全体をビューポートにする */
glViewport(0, 0, $w, $h);
/* 透視変換行列の指定 */
glMatrixMode(GL_PROJECTION);
/* 透視変換行列の初期化 */
glLoadIdentity();
gluPerspective(60.0, (float)$w / (float)$h, 1.0, 100.0);
}
function idle()
{
/* 画面の描き替え */
glutPostRedisplay();
}
function mouse($button, $state, $x, $y)
{
switch ($button) {
case GLUT_LEFT_BUTTON:
switch ($state) {
case GLUT_DOWN:
/* トラックボール開始 */
trackball::Start($x, $y);
break;
case GLUT_UP:
/* トラックボール停止 */
trackball::Stop($x, $y);
break;
default:
break;
}
break;
default:
break;
}
}
function motion($x, $y)
{
/* トラックボール移動 */
trackball::Motion($x, $y);
}
function keyboard($key, $x, $y)
{
switch ($key) {
case 'q':
case 'Q':
case '\033':
/* ESC か q か Q をタイプしたら終了 */
exit(0);
default:
break;
}
}
/*
** メインプログラム
*/
glutInit($argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow($argv[0]);
glutDisplayFunc('display');
glutReshapeFunc('resize');
glutIdleFunc('idle');
glutMouseFunc('mouse');
glutMotionFunc('motion');
glutKeyboardFunc('keyboard');
init();
glutMainLoop();
exit (0);