4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

openFrameworks上での行列演算メモ

Last updated at Posted at 2019-08-11

はじめに

CGなどを勉強しているとどうしてもさけて通れない分野の中の1つとして線形代数があるかと思いますが、今回はそのうちの行列演算などにスポットを当ててメモを残しておきたいと思います.
oF上での行列を扱うにはofMatrix3x3, ofMatrix4x4などと言ったクラスが存在しており、それらを扱って変換行列など用意し行列演算を行っていきます.

行列データの保存形式

行優先、列優先

行列の保存形式には行優先形式と列優先形式というものが存在します.

data = [a_{1}, a_{2}, a_{3}, a_{4}]
  • 列優先(Column-Major)
matrix_{col} = 
\left(
\begin{matrix}
a_{1} & a_{3} \\
a_{2} & a_{4} 
\end{matrix}
\right)
  • 行優先(Row-Major)
matrix_{row} = 
\left(
\begin{matrix}
a_{1} & a_{2} \\
a_{3} & a_{4} 
\end{matrix}
\right)

APIごとでの保存形式の違い

このうちopenFrameworksでは行優先形式、GLSLでは列優先形式が採用されています.
こちらはofMatrix4x4.hに書かれているドキュメントです.

/// oF uses row-vector style by default, meaning that when transforming a vector
/// by multiplying with a matrix, you should put the vector on the left side and
/// the matrix (or matrices) to its right. When multiplying by multiple matrices,
/// the order of application of the transforms is left-to-right. This means that
/// the standard order of manipulation operations is
/// vector * scale * rotate * translate.
///
/// Note that in GLSL, this convention is reversed, and column-vector style is
/// used. oF uploads the matrices to the GL context correctly, but you should
/// reverse the order of your vertex manipulations to right-to-left style, e.g.
/// translate * rotate * scale * vector.

上に記されているように、行優先形式ではベクトルに対してから変換行列を掛け、列優先形式ではベクトルに対してから変換行列を掛けることに注意してください.(行列は掛け算の順序によって計算結果が変わってしまいます.)

サンプルコード

全てではありませんが参考になりそうなコードを貼っておきます.

sample.cpp
void ofApp::setup(){
    scaleMatrix.set(scale->x, 0.0, 0.0, 0.0,
                    0.0 , scale->y, 0.0, 0.0,
                    0.0, 0.0, scale->z, 0.0,
                    0.0, 0.0, 0.0, 1.0);
    
    translateMatrix.set(1.0, 0.0, 0.0, 0.0,
                        0.0 , 1.0, 0.0, 0.0,
                        0.0, 0., 1.0, 0.0,
                        translate->x, translate->y, translate->z, 1.0);
    
    modelMatrix = ofMatrix4x4::newIdentityMatrix();
    modelMatrix.preMult(scaleMatrix);
    modelMatrix.preMult(translateMatrix);
}

void ofApp::draw(){
    cam.begin();
    ofMatrix4x4 viewMatrix;
    viewMatrix = ofGetCurrentViewMatrix();
    ofMatrix4x4 projMatrix = cam.getProjectionMatrix();
  
    ofDrawAxis(1000.0);
    shader.begin();
    shader.setUniformMatrix4f("modelMatrix",  translateMatrix);
    shader.setUniformMatrix4f("viewMatrix",  viewMatrix);
    shader.setUniformMatrix4f("projMatrix",  projMatrix);
    cam.getProjectionMatrix();
    ofDrawRectangle(0.0, 0.0, 300.0, 300.0);
    shader.end();
    
    cam.end();
}
sample.vert
uniform mat4 modelViewProjectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 projMatrix;
uniform mat4 modelMatrix;
in vec4 position;
void main()
{
  vec4 p = projMatrix * viewMatrix * modelMatrix * position;
  gl_Position = p;
}

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?