![]() |
ノート/MPS粒子法プログラムhttps://pepper.is.sci.toho-u.ac.jp:443/pepper/index.php?%A5%CE%A1%BC%A5%C8%2FMPS%CE%B3%BB%D2%CB%A1%A5%D7%A5%ED%A5%B0%A5%E9%A5%E0 |
![]() |
ノート
訪問数 5871 最終更新 2009-06-29 (月) 11:36:53
>> MPS粒子法プログラム2
出力ファイルmps.profをopenGLで表示したい。
ノート/raytracing
和歌山大版OpenGLの使い方 GLUTによる「手抜き」OpenGL入門
mps.profの形式:
0.000000 時刻 1122 粒子総数 0 0.004000 0.004000 0.000000 0.000000 0.000000 6.539697 0 0.012000 0.004000 0.000000 0.000000 0.000000 6.539697 0 0.020000 0.004000 0.000000 0.000000 0.000000 6.539697 種類番号 x座標 y座標 x速度 y速度 圧力 粒子密度
0)Cygwinでのインストール
http://pepper.is.sci.toho-u.ac.jp/index.php?%A5%CE%A1%BC%A5%C8%2Fraytracing
http://www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html#2
1)外枠
http://www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html#3
http://www.ics.kagoshima-u.ac.jp/edu/expIV3/basic-of-opengl.html
2)丸を描く
openGLには円を書く関数が無い。
方法1: pointを使い、pointの大きさを大きく(glPointSize(5); )する。
この時、glEnalbe(GL_POINT_SMOOTH)をしないと、形が丸くならない。
http://www.talisman.org/opengl-1.1/Reference/glPointSize.html
http://www.ics.kagoshima-u.ac.jp/edu/expIV3/basic-of-opengl.html
3)色を付ける
ウィンドウの色設定
void glClearColor(r,g,b,a); // 消去色を指定
void glClear(GL_COLOR_BUFFER_BIT); // 消去を実行
http://www.ics.kagoshima-u.ac.jp/edu/expIV3/basic-of-opengl.html
描画対象の色設定
void glColor3f(r,g,b); // R,G,B成分を[0,1]の範囲で指定する
void glColor3f(r,g,b,a); // R,G,B,Alpha成分を[0,1]の範囲で指定する
あと、オブジェクトの色という話もあるが、省略
http://www.ics.kagoshima-u.ac.jp/edu/expIV3/basic-of-opengl.html
4)アニメーション
http://wisdom.sakura.ne.jp/system/opengl/gl10.html
#include <GL/glut.h> GLfloat top = -0.9; void display(void) { glClear(GL_COLOR_BUFFER_BIT); glPointSize(5.0); glColor3f(0,0,0); glBegin(GL_POINTS); glVertex2d(top, top); glEnd(); glFlush(); } void init(void) { glEnable(GL_POINT_SMOOTH); glClearColor(1.0, 1.0, 1.0, 1.0); } void timer(int value) { static GLboolean isUp = GL_TRUE; if (top > 0.9) isUp = GL_FALSE; else if (top <= -0.9) isUp = GL_TRUE; top += (isUp == GL_TRUE ? 0.01 : -0.01); glutPostRedisplay(); glutTimerFunc(5, timer,0); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutDisplayFunc(display); init(); glutTimerFunc(100, timer, 0); glutMainLoop(); return 0; }
最後に、生成した画像を「取り出す」方法。取り出してファイル化するなどが必要なため。
基本は、glReadBuffer()関数を使う。
http://opengl.jp/oglfaq/miscellaneous.htm
http://sky.geocities.jp/freakish_osprey/opengl/opengl_capture.htm
取り出した結果を所定のファイル形式に変換するためのライブラリがたくさんある。
http://opengl.jp/oglfaq/miscellaneous.htm
が、今欲しい形(MJPEGのyuv4mpegpipe方式)にはならないだろう。自分でプログラムを書くしかなさそうだ。
たとえば、こんなプログラム MPSView.c を書いてみた。
ダブルバッファにしないと絵がちらつく。ダブルバッファ導入。
図の大きさは適当。(きちんとスケーリングを計算していない。そのままx,yを与えた。
操作のボタン等は作っていない。いずれやればいいだろう。
こんなプログラム &ref(): File not found: "mps.c" at page "yylab/MPS粒子法プログラム"; GLmps.c になった。これでoregano上で動く。
念のため、使ったMakefileは Makefile
元のプログラムを読みながら、全体の構造を入換えた。
こんな方法も可能なことを思い出した。まずmpsプログラムでは元のままで、ただし出力をファイルに書くのではなく、UNIXのPIPE (FIFO) に書き出すことにする。
UNIXの(名前つき)PIPEは、コマンドmkfifoで作ることが出来る。たとえばこのページを参照。要するにコマンドプロンプトから、mkfifo mps.prof としてやると、名前mps.profのパイプが作られる。
パイプは、プログラムからはストリームに対する入出力でアクセスできるから、mpsプログラムの出力ファイルとしてのmps.profの代わりに、名前つきパイプmps.profに出力するようになる。Cのソース上は何も変更は要らない。
表示側のプログラムMPSViewは、ファイルmps.profを読む代わりに、名前つきパイプmps.profを読ませる。これもCのソース上は何も変更は要らない。
それで、一方のコマンド入力画面からMPSViewを起動し、もう1つ別のコマンド入力画面からmpsを起動すると、表示ウィンドウが開き、実行が始まる。
名前つきパイプではなくて、シェル上の「|」縦棒を使っても同じことになる。但し、プログラムを、mps側はstdoutに書き出し、MPSView側はstdinから読み込むように書き直す必要がある。その上で、コマンド入力画面から、mps | MPSView とすればよいだろう。