ドーナツモデルで光源処理
久しぶりのOpenGLプログラムです。今日は、トーラス(ドーナツですね)を描画します。まだ光源処理のサンプルを作成していなかったので、光源も使用します。まず、トーラスですが、図に示すような感じで、半径16の円をx方向に平行移動し、y軸回転させることで生成しています。円は、64個の頂点で分割されており、y軸回転も64分割です。プログラムでは、描画性能を上げるため、独立三角形ではなく、64個の三角形ストリップを用いています。キーボードで「d」を押せば、フィル描画、ライン描画(ワイヤフレーム)、ポイント描画とモードがトグルしますので、どのような三角形でできているかがわかると思います。

プログラムではFUTL_MakeTorus関数で、頂点の位置座標、法線座標、テクスチャ座標を作成します。同時にテクスチャ(BMPファイル)も読み込んでいます。内容はプログラムを見ていただければ、分かると思います。初期化時に、FUTL_MakeTorusでトーラスモデルを作成し、GLUTの描画コールバック関数内でFUTL_DrawTorusを呼び出し、毎フレーム描画しています。
int main(int argc, char *argv[])
{
: : 途中略 : :
/* トーラスモデル(ドーナツ)の作成 */
if (FUTL_MakeTorus(texFile) < 0)
{
return -1;
}
: : 途中略 : :
}
/* 描画のコールバック関数 */
void display(void)
{
: : 途中略 : :
/* トーラスの描画 */
triangles = FUTL_DrawTorus(count);
: : 途中略 : :
}
光源処理は、光源とマテリアルを設定することで行います。光源設定はFUTL_SetLight関数で行っています。
/* 光源設定 */
int FUTL_SetLight(
int lightID,
FLight *lpLight
)
{
glLightfv(lightID, GL_AMBIENT, (GLfloat *)(&(lpLight->ambient)));
glLightfv(lightID, GL_DIFFUSE, (GLfloat *)(&(lpLight->diffuse)));
glLightfv(lightID, GL_SPECULAR, (GLfloat *)(&(lpLight->specular)));
glLightfv(lightID, GL_POSITION, (GLfloat *)(&(lpLight->position)));
return 0;
}
光源パラメータは、次のような値を設定しています。今回、光源には平行光源を使用しており、+Z方向(0.0, 0.0, 1.0)から光を当てているような設定です。
/* 平行光源 */
FLight light = {
0.0f, 0.0f, 1.0f, 0.0f, /* postition(w=0.0fは平行光源) */
1.0f, 1.0f, 1.0f, 1.0f, /* ambient */
0.8f, 0.8f, 0.8f, 1.0f, /* diffuse */
1.0f, 1.0f, 1.0f, 1.0f, /* specular */
0.0f, 0.0f, -1.0f, /* spotDirection */
0.0f, /* spotExpornent */
180.0f, /* spotCutoff */
1.0f, 0.0f, 0.0f /* attenuation */
};
マテリアルは、FUTL_SetMaterial関数で行っています。単純に全パラメータを設定しています。
/* マテリアル設定 */
int FUTL_SetMaterial(
FMaterial *lpMaterial
)
{
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,
(GLfloat *)(&(lpMaterial->ambient)));
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
(GLfloat *)(&(lpMaterial->diffuse)));
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,
(GLfloat *)(&(lpMaterial->specular)));
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION,
(GLfloat *)(&(lpMaterial->emission)));
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS,
(GLfloat *)(&(lpMaterial->shininess)));
return 0;
}
マテリアルパラメータは、torusmodel.cの中に定義されており、次のようになっています。
/* モデルのマテリアル */
static FMaterial material = {
0.2f, 0.2f, 0.2f, 1.0f, /* ambient */
0.8f, 0.8f, 0.8f, 1.0f, /* diffuse & alpha */
1.0f, 1.0f, 1.0f, 1.0f, /* specular */
0.0f, 0.0f, 0.0f, 1.0f, /* emission */
64.0f /* shininess */
};
ということで、プログラムをコンパイルして実行すれば、次のような絵がでるはずです。キーボードで「p」ボタンを押せば、一時停止することができます。

この状態で、「d」ボタンを押せば、次のようなワイヤーフレーム表示になります。

ワイヤーフレーム表示にした時の方がかなり高速ですね。しかし、「文字描画と時間測定」で説明したように、ディスプレイの垂直同期をはずすと、ワイヤーフレームよりも、通常のフィル描画の方が圧倒的に高速になりますので、恐らくフィル描画(通常の描画)の方が高速だと思います。
最新の7件
OpenGL
電子工作
玄箱HG
- ClamAVのアップデート
- Smartyも入れてみる
- etchでPHP4->PHP5
- etchでのSamba設定
- etchでのメール設定
- 玄箱HGのetch化
- Webdruidでログ解析
- PEARも入れてみる
- 玄箱WEBのUTF-8化
- phpMyAdminでMySQL
- postmasterの変更
- ウィルスメール対策
- SPAMメール対策
- メールサーバ(IMAP)
- メールサーバ(Postfix)
- 猫にXOOPS
- PHPも入れてみる
- MySQLを入れてみる
- Subversion導入
- WebDav導入
- Apacheのrewrite機能
- Apacheディレクトリ設定
- Apache1.3->2.0
- ddclientの設定
- 静かな玄箱
- ユーザ追加