現在地: メニュー >> 実践編07
INDEX:実践編06 << 実践編07 >> 実践編08

行列と座標変換


赤本にも書いてある事だが、OpenGLでは以下のようにして、
3次元の座標をウィンドウに描画する。





例えば、「reshape関数」内で以下のような記述をしていた。
void reshape(int w, int h)
{
    glViewport(0, 0, w, h);//ビューポートの設定
    
    glMatrixMode(GL_PROJECTION);  //射影行列を設定するために「GL_PROJECTIONモード」に
    glLoadIdentity();  //行列の初期化

    gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0); //視野の設定


    glMatrixMode(GL_MODELVIEW); //これ以降の内容はモデルビュー行列に設定する
    glLoadIdentity();  //行列の初期化
    gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);//視点の設定

}
つまり、
「display関数」内の描画前に、射影行列、モデルビュー行列、ビューポートを設定する事で
透視投影が行われ、ウィンドウに描画されるのである。


ここで、これらの行列を取り出す関数として、「glGet*」関数がある。→リファレンス
この中の「glGetDoublev」や「glGetFloatv」を使う事で上述した行列を取り出せる。

【例】
float ModelView[16];//モデルビュー行列
float Projection[16];//射影行列
… …
	//射影行列を取得
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(30,static_cast<double>(WindowSize.first)/WindowSize.second,0.1,200 );
	glGetFloatv(GL_PROJECTION_MATRIX,&Projection[0]);
		
	//モデルビュー
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(eye[0],eye[1],eye[2], 0,0,0, 0,1,0);
	glGetFloatv(GL_MODELVIEW_MATRIX,&ModelView[0]);

そして、「glLoadMatrix関数」でその行列を呼び出せる。

【例】
	glMatrixMode(GL_PROJECTION);
	glLoadMatrixf(&Projection[0]);
	glMatrixMode(GL_MODELVIEW);
	glLoadMatrixf(&ModelView[0]);


【メモ】
OpenGLの行列は、一般的な横方向の並びではなく、以下のように縦方向にならんでいる。




メモ


GeeKs3D.comより


上述のように行列をロードするだけでもよい事を考えると、OpenGLの関数なしで透視投影行列が作成可能である。

void BuildPerspProjMat(float *m, float fov, float aspect,float znear, float zfar)
{

  float xymax = znear * tan(fov * 0.00872664626);
  float ymin = -xymax;
  float xmin = -xymax;

  //スクリーンの横、縦を計算
  float width = xymax - xmin;
  float height = xymax - ymin;

  //奥行き値関係
  float depth = zfar - znear;
  float q = -(zfar + znear) / depth;
  float qn = -2 * (zfar * znear) / depth;

  //アスペクト比関係
  float w = 2 * znear / width;
  w = w / aspect;
  float h = 2 * znear / height;

  //行列に値を設定
  m[0]  = w;
  m[1]  = 0;
  m[2]  = 0;
  m[3]  = 0;

  m[4]  = 0;
  m[5]  = h;
  m[6]  = 0;
  m[7]  = 0;

  m[8]  = 0;
  m[9]  = 0;
  m[10] = q;
  m[11] = -1;

  m[12] = 0;
  m[13] = 0;
  m[14] = qn;
  m[15] = 0;
}

... ...

float m[16] = {0};
float fov=30.0f; // in degrees
float aspect=4.0/3.0f;
float znear=0.1f;
float zfar=200.0f;

BuildPerspProjMat(m, fov, aspect, znear, zfar);

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(m)

... ...


サンプルコード

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます