OpenGLで任意の行列を使いたい

OpenGLで任意の行列を適用したいときは

glMultMatrixd(const GLdouble *m)か
glMultMatrixf(const GLfloat *m)を使う.

これは現在の行列(glMatrixModeで指定しているもの)に任意の行列を掛ける関数.

GLdoubleとGLfloatはOpenGLの定義する型だが,doubleかfloatと同じものと考えて良い.


使うときは
glMultMatrixd(&m[0]);
のように書く.

ここでmは掛けたい行列でGLdouble型の要素数16の行列.


サンプルコード

#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <gl/glut.h>

//!1
//X,Yそれぞれ0.5,0.25倍拡大
GLdouble m1[16] = {
	0.5,0,0,0,
	0,0.25,0,0,
	0,0,1,0,
	0,0,0,1
};
//45度回転cos(45°)=sin(45°)=0.707106781...
GLdouble m2[16] = {
	0.707106781,0.707106781,0,0,
	-0.707106781,0.707106781,0,0,
	0,0,1,0,
	0,0,0,1
};

void Init() {
	glutInitWindowSize( 200, 200 );
	glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA );
	glutInitWindowPosition( 0, 0 );
	glutCreateWindow( "任意の行列の適用" );
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D (-100, 100, -100, 100);
}

void Render() {
	glClearColor(0.0, 0.0, 0.0, 1.0);
	//行列適用前(白)
	glBegin(GL_LINE_LOOP);
		glColor3d(1.0, 1.0, 1.0);
		glVertex2d(-60, -60);
		glVertex2d(-60,  60);
		glVertex2d( 60,  60);
		glVertex2d( 60, -60);
	glEnd();
	//行列適用後(赤)
	glMultMatrixd(&m2[0]); //!2
	glMultMatrixd(&m1[0]); //!2
	glBegin(GL_LINE_LOOP);
		glColor3d(1.0, 0.0, 0.0);
		glVertex2d(-60, -60);
		glVertex2d(-60,  60);
		glVertex2d( 60,  60);
		glVertex2d( 60, -60);
	glEnd();
	glFlush();
}

int main( int argc, char **argv ) {

	glutInit( &argc, argv );
	Init();
	glutDisplayFunc( Render );

	glutMainLoop();
}

!1
ここで注意するのは

行列
\begin{equation}M=\begin{pmatrix} m_{11} &m_{12} &m_{13} &m_{14}\\m_{21} &m_{22} &m_{23} &m_{24}\\m_{31} &m_{32} &m_{33} &m_{34}\\m_{41} &m_{42} &m_{43} &m_{44}\end{pmatrix}\end{equation}

配列mでは

m =
{
	m11, m21, m31, m41,
	m12, m22, m32, m42,
	m13, m23, m33m m43,
	m14, m24, m34m m44
}

と対応していることである.

!2
またアフィン変換の性質から

拡大→回転という順の変換を行いたいときは

行列は
回転→拡大という順番で掛ける必要がある.
試しに逆でやってみると全然違う結果になる(やってみると良い).

サンプルソースコードの細かなOpenGLの記法は,基礎中の基礎なので説明割愛.



正直glTranslate,glScale,glRotateがあればことが足りるので,役には立たないだろう.

実行結果