English
|
Information in this page is obsolete.
This page will be erased by Feb.2005. Thanks.
Back to TOP>LINUX>
Let's begin 3D with Eggx(このページは2006年12月現在管理しておりません。)
libeggx3d :(X11-UNIX/LINUX用三次元ワイヤ・フレームする為の)
EGGXグラフィクス・ライブラリ用
追加ライブラリ
かっちょいいOpenGL や Direct X のこの時代に、何故にワイヤフレーム?
答えは簡単、ワイヤフレームは「簡単」だからです
光源も陰面処理もテキスチャマッピングも何もいらない、ただ線を引くだけ。
そう、line3d()とpset3d()だけで線も引けるし、点も打てる。
ウィンドウ開けるのもたった一つの関数gopen3d()で。簡単でしょ?
それでいて三次元。だからワイヤフレーム!
libeggx3d は簡単だと自負していますが, ちょっと本格的なことをしようと思ったら正直なところパワー不足です。
OpenGL ファンの方は是非 OGLIS
ホームページ(英語のみ)もご覧になってください。OGLIS --- OpenGL is Simple はEGGXの技術を
導入して作られております。パワフルなOpenGLを使いつつ、EGGX譲りのマルチ・ウィンドウプログラミングの
簡単さと、ライブラリの使用感の単純さ、また、C言語コードのどこにでも埋め込める手軽さ、
勿論GTK+/GDKやQTとの親和性をも持ち合わせた、新しいライブラリです。
あなたは、
人目の来訪者です。どうぞごゆっくり。
written on January 28th, 2003
On March 15th, 2004,
updated to libeggx3d029r1 due to
major change in EGGX from EGGX079 to EGGX080
written by Hidde F. K.
サンプル・スナップショット
News 2010年11月15日、libeggx3d_020シリーズに戻し、派生させた物をlib3eggx3d_03xシリーズとしました。
libeggx3d_029シリーズは現在の本家EGGXには対応出来ておりませんので。
History:
`名無し' から `002.'にバージョンが引き上げられました。 (February 11th,
2003)
`002' to `004'にバージョンが引き上げられました。 (March 27th, 2003)
バージョン004から010r1への変更:
EGGX と同じくマルチウィンドウ化に対応しました。本来あるべき姿です。
マルチウィンドウ化に伴い、`004' から `010r1'にバージョンが引き上げられ
ました。(Sept. 4th,2003)
`020r1'ではダイナミックリンキングライブラリとしました。最適化も若干な
されました。(Nov.6th, 2003)
`029r1'でしばらく気付かなかった本家のバージョンアップ EGGX080に対応しました。
2010年11月15日をもって'029r1'は没としました。
'020'シリーズから派生した'030'シリーズを今後お使い下さい。
簡単な紹介:
libeggx3dは3次元表示を可能にする
EGGX用追加ライブラリです。
libeggx3d が出来る事:
ワイヤ・フレーム・グラフィクスを描くこともさながら、
条件付きで陰面処理されたグラフィクスを描くこと。ワイヤ・フレームのみに
限っているので軽いです。DRIを使わない MESAよりも30%位速いです。
(gears.cで計測しました。)
複数のウィンドウに同時に描画する事も得意です。
で、得意なこと:
計算結果を三次元ワイヤフレームグラフィクスで表示すること。
陰面処理は可能ですがあまり得意ではありません。
サンプル
必要な環境
1. 山内千里様がご提供されている EGGX ライブラリ及びそれらが使える環境。
http://phe.phyas.aichi-edu.ac.jp/~cyamauch/eggx_procall/ からダウンロードできます。
2. UNIX X11コンパチブルでC言語での開発が出来る環境。 (3D accelerationハードウェアは必要ありません!)
試した環境:
Debian GNU/Linux 3.0 with Athlon XP 2000+ CPU, 512Mbyte RAM, ATI 3D Rage
128 video board.
今後の課題:
まず関数を全て‘EGGX3D’から始め、EGGX080(本家)との違和感をなくす。
これはバージョン030で対応させる予定。
画像マッピング、立体視、その他いろいろ。.
TODO:2011年正月をめどに、本家の090-093シリーズに対応できるように
このページを全面的に書き換えるつもりでおります
Contents:
紹介
コンパイルトラブルに見舞われた方へ
EGGXとは
libeggx3d とは
インストール
インストールの前に(旧バージョン利用の方へ)
インストール
ローカルディレクトリにライブラリを置いて使う方法
資料
資料:関数の仕様
EGGXとは?
有名なライブラリなので説明するまでもないでしょう、が一応触れておきます。山内千里様が開発・管理されているライブラリで、http://phe.phyas.aichi-edu.ac.jp/~cyamauch/eggx_procall/.からダウンロードできます。X11絵画関数以外何も使わないシンプルな、しかし強力なライブラリです。``Software
Design''2003年1月号でも詳しく紹介されていますので、ご参照下さい。
EGGXとは山内千里様が開発されたUNIX(Linuxを含む)用2次元可視化ライブ
ラリ、及びそれを使いやすくする為のコマンドを合わせた総称です。含まれ
ているもっとも主な(FORTRANの事を考えなければ唯一の)実行コマンド「egg」
コマンドは単にEGGXで必要なライブラリ(x11やEggXライブラリ)等をリン
クしてくれる以外はGCCとまったく同じ作法で使えるコマンドです。誤解を
恐れずに言えばCコンパイラを別の名前で呼び出しているだけのものです。
現にEGGXの機能を用いるにはGCCからでも利用できます。設計思想が大変素
晴らしく、8bit時代のグラフィクスの扱いの簡単さを最新の技術で実現して
おり、初心者のプログラム学習から専門家のデータの可視化ツールの為の利
用まではば広く使える、大変強力なライブラリ及びコマンドセットとなって
います。またFORTRANからも利用出来るようになっています(ここでは触れ
ませんが)。
で、 ``libeggx3d''て何?
``libeggx3d'' とは、EGGX上で、三次元グラフィクスが扱えないかと模索し、
私(小渡 英)が作ったライブラリです。
知識の無さからワイヤフレームグラフィクスしか主に扱えませんが、
うまくごまかせば、陰面処理されたポリゴンも扱えます。
OpenGL/MESAは使わない方針です。OpenGLを使えば三次元を扱う上で近道ですが、
なんと言っても複雑で大きく、ハードウェア資源を必要とします。
世の中にはOpenGLを使えない環境もきっとあるでしょう(?)。
X11しか使わないことにこだわりました。
`libeggx3d'は
EGGX及びX11のみを利用していますので、EGGXとX11が動く環境さえ整っていれば手軽に三次元
(但し針金)グラフィクスが楽しめます。Visualizing(可視化)ツールに使えるのではと
考えて作りました。
インストールした後はeggコマンドあるいは
C-Compiler(GCC,CC等)から引数に`` -leggx3d'' を付け加
える事で利用出来るようになります。
ごたくくだくだ
そもそも始まりは私の高校生時代PC-9801全盛の時代にまでさかのぼります。
当時は16Bitパソコンが巷に出回り始めたばかりで3次元グラフィクスを手軽に扱うなぞ
出来ませんでした。(たとえ針金グラフィクスであろうと。)
私は納得しませんでした。何で2次元で扱えるPset(機種によってはPlot)やLine
(同じくDrawto等)のコマンド(当時はBASIC全盛です。)あるいはC言語関数
(当時はC言語は画期的な言語でした。)があるのに、3次元を扱えるPsetやLine
コマンドあるいは関数が無かったのでしょうか。当時最新言語であったC言語さえ使えば、
Pset3dやLine3dなど簡単に関数かできそうでした。
で、独学でグラフィクスの勉強し作りました。Pset3dとLine3dを。
しかも当時巷にあふれていた単なる視点座標系ではなく実際に使いやすいであろうと思われる、
ワールド座標系を用いた物を。今から思えばアイディアは悪くなかったと思います。
しかし当時のパソコンではそこまでが限界でした。
というのは死ぬほど遅いのです。当時はグラフィクスボードはおろか、
浮動小数点コプロセッサも高値の花でしたから。
一枚の地形図を書くのも隠面処理からクリッピングまでして書き上げるとなると
10Mhzマシンで一時間近くかかりました。
当時としては速かったんですけど。その時の基本仕様を述べます。
視点と目標点(どこを見ているかという点)を三次元ワールド座標で指定し、
それを基に点を打つ関数及び線を書く関数を用いて描く、
それだけです。そして現在の`libeggx3d' もそれを踏襲しています。
(隠面処理機能については省略しがちですが。)
自重気味に小文字で命名したのですが、
libeggx3dのお粗末さには自分でも恥ずかしくなるくらいで、小文字であろう
ともeggxを名乗るに値しないライブラリだと考えています。(これを読まれた
皆様、何か良い命名があったらお教え下さい)。とりあえず現在の所、針金
(ワイヤフレーム)グラフィクスのみに使うのが妥当な利用方法だと考えてい
ます。基本的にはワールド座標系内で視点と目標点を定めた後は単に三次元か
ら二次元に座標変換するだけのライブラリですから、物体の前後処理さえ施せ
ばポリゴンも扱えます。で、一応ワールド座標から視点座標に写す際に視点か
らの距離をもとめる関数も用意してありますので、力の余っている方はポリゴ
ンの利用もチャレンジしてみて下さい。(ポリゴンを描く関数も用意してあり
ます。使い道あまり無いですが。)
ライセンス
なお、libeggx3d と EGGXは同時に利用で
きます。いくつか機能の重複する関数もありますが、
それらはgopen3d()関数で
開いた限りlibeggx3d関数の方がEGGX関数の上位互換となっております。
``libeggx3d'' は GNU Public License下で配布します。.
新しい``libeggx3d''をインストールする
前に
ダイナミックリンクにしたのでこれまでのeggx3d.h, libeggx3d.a
は削除して下さい。恐らく、それぞれ /usr/local/include と
/usr/local/lib に配置されていると思います。
``libeggx3d''はEGGX追加ライブラリです。
EGGX を 先にインストールして下さい。
山内千里様が提供してくださっているウェブサイトから
EGGX http://phe.phyas.aichi-edu.ac.jp/~cyamauch/eggx_procall/ をインストールして下さい。
2004年3月15日現在最新のバージョンはEGGX080です。
2010年11月現在のEGGXの最新バージョンはEGGX09xであり、
libeggx3d_029シリーズで動作しないことが判明しました。
ので、libeggx3d_029シリーズのリンクを外しました。
古いlibeggx3d_020r2シリーズからlibeggx3d_030r1.tar.gzを派生させました。
EGGXを設定し、それから libeggx3d_030r1.tar.gz,
をこのページからダウンロードし以下の説明にある通り設定して下さい。
これには肝心なlibeggx3d.c と eggx3d.h, そしてデモ・プログラムが含まれています。
環境に応じてお使い下さい。
ダウンロードしたら
$ tar tzvf ./libeggx3d_0xxrx.tar.gz
を実行しソースファイルしか含まれていないことを確認されるのをお勧めします。その後コマンドラインから
$ tar xzvf ./libeggx3d_0xxrx.tar.gz
で、解凍して下さい。
その後
$ ./configure
$ make
$ su
# make install
# ldconfig
を実行すれば、 libeggx3d.a が/usr/local/lib/に、eggx3d.hが/usr/local/include/に配置されます。私の環境ではうまく動きますが、他の環境では試していません。
3D プログラムは次のようにコンパイルして下さい。:
$ egg -o axis3d axis3d.c -leggx3d
前もって ソースプログラム、この場合は axis3d.cにヘッダファイルをインクルードしておくのを忘れないで下さい。(^^;
#include <eggx.h>
#include <eggx3d.h>
./configure;make;su;make install がうまく行かない場合
$ egg -o axis3d axis3d.c libeggx3d.c
でコンパイル可能です。ヘッダファイルの配置位置に注意して下さい。ローカルディレクトリに入れる場合は以下のようにして注意して下さい。
#include <eggx.h>
#include "eggx3d.h"
/* note quoted with double quotation mark
in this case. */
私のライブラリを使っていただいて、
「ここが分かりにくかった、」という指摘を受けましたので、
ここに書きます。症状: 1.コンパイル出来ない:以下のようなメッセージで、コンパイル出来ない場合が確認されました。
./axis3d: error while loading shared libraries: libeggx3d.so.1: cannot
open shared object file: No such file or directory取り敢えず、大変乱暴な解決方法ですが、#
vi /etc/ld.so.conf
で、以下の行を確認します。
/usr/local/lib
無ければ、空白、空行、が無いように、上記の行を入力します。ルートから
# ldconfig
入力します。即、使えるようになると思いますが、自信はありません
資料:ライブラリ
libeggx3dの使い方:
バージョン010r1から関数の数が11つから19に増えました。
しかしこの変更は主なしよう変更であるマルチウィンドウ化に伴うもので、
必ず使わなければならない関数はむしろその半分です。
`libeggx3d'関数群:
以降、座標設定単位はことわりの無い限りメートルです。
int gopen3d(float xsize, float ysize);
xsize,ysize で指定されたドットの画面を開き、戻り値としてwindow 番号を返します。
window 番号は`libeggx3d'関数で必ず使われる値ですから大事に保存して下さい。
ここで、デフォルトとしてgset_screen_distance(win,0.4)(後述),gset_look_at(win,0,0,0),
gset_eye_at(win,100,280,600)が設定されます。これは17インチモニタ800x600ドットの
ウィンドウでア100メートルの立方体がウィンドウ内に入る設定です。
gopen()関数の上位互換関数です。
void gclose_window(int win)
win で指定されたウィンドウ番号のウィンドウを閉じ、画面から消去します。
役割はEGGXにおけるgclose()関数と同様で上位互換性があります。
void gclose3dall(void)
gopen3d()関数やEGGXのgopen()関数で開いた全ての関数を閉じ画面から消去するほか
メモリ空間を利用していた構造体配列を開放します。EGGXのgcloseall()を内部で
呼び出します。gopen3d()関数を使用した場合は必ず最後にこの関数を実行して下さい。
void pset3d(int win, float x, float y, float z);
設定関数gset_screen_distance(),gset_look_at(),gset_eye_at()等や場合によっては
gopen3d()のみで設定された条件を基に指定されたワールド三次元座標に点を打ちます。
色はEGGX関数であるnewpen(),newrgbcolor(),newcolor(),等を用いて設定して下さい。
また、この関数はline()(後述)とdrawarrow3d()(後述)の起点座標を設定するのにも
用いられます。
void line3d(int win,float x, float y, float z,int mode);
設定関数gset_screen_distance(),gset_look_at(),gset_eye_at()等や、場合によっては
gopen3d()のみで設定された条件を基に指定されたワールド三次元座標に、
mode=PENDOWN の場合には線を引き、mode=PENUPの場合には座標のみを記憶し、
次のmode=PENDOWN時のline3d()関数、及び、drawarrow3d()関数の起点となります。
色はEGGX関数であるnewpen(),newrgbcolor(),newcolor(),等を用いて設定して下さい。
この関数の最後の引き数であるmodeにはPENUPもしくはPENDOWNを指定します。
使い方はEGGXのline()関数を踏襲しているのでEGGXマニュアルを見れば自明ですが、
mode=PENDOWNでペンを下ろして描画、mode=PENUPでペンを上げて移動と
考えて頂ければ分かりやすいと思います。
また PENUPをmodeに指定するとpset3d()関数と同様、次のPENDOWNモードのline3d()
関数の起点を指定する事になります。この辺りはEGGXのline()関数と同じです。
void circle3d(int win, float radius, float centerx, float centery, float centerz
,float normalx, float normaly, float normalz);
設定関数gset_screen_distance(),gset_look_at(),gset_eye_at()等や場合によっては
gopen3d()のみで設定された条件を基に指定されたワールド三次元座標に円を描きます。
色はEGGX関数であるnewpen(),newrgbcolor(),newcolor(),等を用いて設定して下さい。
radius には半径(単位はメートル)を、中心座標は(centerx, centery, centerz)で指定された
ワールド座標系を、また描く円の向きについては円の面に垂直なベクトル、つまり
法線ベクトルを(normalx, normaly, normalz)で指定します。
void drawarrow3d(int win, float xhead, float yhead, float zhead
,float s, float w, int 10*i+j );
設定関数gset_screen_distance(),gset_look_at(),gset_eye_at()等や場合によっては
gopen3d()のみで設定された条件を基に指定されたワールド三次元座標に矢印を描きます。
起点はpset3d()関数、あるいはline3d()関数でPENUPを指定した時の座標で指定します。
色はEGGX関数であるnewpen(),newrgbcolor(),newcolor(),等を用いて設定して下さい。
形はsが矢印全体の長さに対する矢の部分の長さの割合を0.0から1.0の間で、
wが矢印全体の長さに対する矢の部分の「広がり」の幅の割合を0.0から1.0の間で指定します。
矢の種類及び矢の先端の形を指定する
i と j の関係はEGGXマニュアルの2.5.25drawarrow()の項を参照して下さい。
とりあえず、iには11を、jには2、4もしくは6を指定すれば、
つまり最後の引数には112,114,もしくは116を指定すると一般的にイメージされる矢印が
描けると思います。(因みにj=6の場合塗りつぶされた矢の先端を、j=2の場合には中心線を
残し、空洞な矢の先端を、j=4の場合には更に省略された矢の先端を描きます。)
void gcoord3d_to_2d(int win, float x, float y, float z, float *fx, float *fy);
この関数はワールド座標(x,y,z)で指定された点を画面上EGGXで描ける(&fx,&fy)に返します。
EGGXのdrawstr()関数やdrawsym()関数などをワールド座標に相当する部分に 描きたい場合などに御利用下さい。
当初の`libeggx3d'はこの関数しかなく、変換された座標をEGGXのline()で結んで線を引くなど
描画に用いていました。
より詳細な設定関数:
void gset_eye_at(int win, float vx, float vy, float vz);
ワールド座標系(右手座標系)における視点を定めます。この関数の設定は全ての
描画関数に影響を及ぼします。少しづつこの関数の設定を変え再描画を繰り返すと
空を飛んでいるような効果を得られます。
立体視する為の画像を制作するのに便利です。
void gset_look_at(int win, float hx, float hy, float hz);
ワールド座標系(右手座標系)における目標点(ワールド座標系の中の
どこを見つめているか)を定めます。少しづつこの関数の設定を変え再描画を繰り返すと
一点から様々な方向を見ているような効果を得られます。
この関数の設定は全ての描画関数に影響を及ぼします。
void gset_screen_distance(int win, float screen_distance);
screen_distance 変数は現実世界の眼からディスプレイスクリーンモニタ迄の距離を
基に微調整して設定して利用して下さい。この変数は眼からディスプレイまでの距離
を表すだけでなく、画像の拡大率も同義で表しているので、画像の拡大、縮小しての
描画にも御利用下さい。
この関数の設定は全ての描画関数に影響を及ぼします。
その他の関数:
平面座標系設定関数:
window_range(int win, float sx, float sy, float ex, float ey);
この関数はEGGXのwindow()関数の上位互換関数です。詳細はEGGXマニュアルの
window()関数の項を見て下さい。
この関数は`libeggx3d'を利用しながらEGGXの平面座標系をデフォルト値から
変更したい時の為に用意しました。特に利用する必要はないので、「その他の関数」
の項に入れました。
描画関数:
fillpoly3d(int win, float x[], float y[], float z[], int datanum);
datanum個の頂点を持つ三次元ポリゴンを描きます。頂点情報は
x[]配列,y[]配列,z[]配列にしまわれた物を利用します。描いた画面上の位置は
正確ですが、前後処理(奥行き処理)がなされません。利用する場合はgdepth()関数(後述)
を用いて前後情報を得、その後、遠くから近くへの順番に描画しないと正確な
画像は得られません。奥行きの距離の情報はgdepth()で得られます。
またqsort関数が役に立つでしょう。
この部分が使いにくい為、「その他」の関数の中にまとめました。
色はEGGX関数であるnewpen(),newrgbcolor(),newcolor(),等を用いて設定して下さい。
float gdepth(int win);
最後に用いられた関数の点座標を基に点の距離(奥行き方向)を返します。
具体的にはpset3d(win,x,y,z),line3d(win,x,y,z,PENUP),
gcoord3d(win,x,y,z,NULL,NULL)で利用された座標に関する情報を返します。
視点座標系座標を得る為に、またそれを使う為に用意された関数:
gviewx(int win);
gviewy(int win);
gdepth(int win) と合わせて最後に変換された座標を視点座標系(左手座標系)として
最後に用いられた関数の点座標を基に点の距離(奥行き方向)を返します。
具体的にはpset3d(win,x,y,z),line3d(win,x,y,z,PENUP),
gcoord3d(win,x,y,z,NULL,NULL)で利用された座標に関する情報を返します。
変換された後の視点座標系座標は(gviewx(win),gviewy(win),gdepth(win))となります。
gcoordv3d_to_2d(int win, float x, float y, float z, float *fx, float *fy);
視点座標系(左手座標系)座標をEGGXで利用出来る
平面座標 (fx, fy)に返します。視点座標系座標(左手座標系座標)は
(gviewx(win), gviewy(win), gdepth(win) )で得られます。
詳しくはgviewx()関数,gviewy()関数,gdepth()関数の項を参照して下さい。
おまけ的関数:
void gget_eye_at(int win, float *vx, float *vy, float *vz);
gset_eye_at()関数で指定した視点座標を(&vx, &vy, &vz)に返します。
デフォルト値を得る為に作った、おまけ的関数です。
void gget_look_at(int win, float *hx, float *hy, float *hz);
gset_look_at()関数で指定した目標点座標を(&hx, &hy, &hz)に返します。
デフォルト値を得る為に作った、おまけ的関数です。
何か御意見、a庫fkowata atmark g02 dot itscom dot net
までメールを下さい!
/eof
References:([1] [2] and [4] are written in Japanese)
[1] PC9801/PC-8801 3次元グラフィックス入門、永山嘉昭・著、日刊工業新聞社、昭和61年(1986年)4月25日発行
[2] 実習グラフィックス (アスキー・ラーニングシステム2実習コース)、佐藤義雄・著、アスキー出版局、1986年6月25日発行
[3] ANGEL, Edward, Interactive Computer Graphics --- A Top-Down Approach Using OpenGL, Third Edition, Addison-Wesley, Reading, MA, 2003
[4] YAMAUCHI,Chisato, EGGX/ProCALL version 0.78 (EGGX manual), Dec.19th, 2002
Back to TOP>LINUX


多摩丘陵の一部。標高は十倍に拡大。実際には非常になだらかな地形です。
近隣に建設予定の公園の予想図

|