第 7 章 座標変換
7.5 変換行列を使った座標変換
クが発生している状態であり、式 (40) や式 (41) で r や h を求めることができません。その場 合は、たとえば h = 0 とし、m0 と m14 の関係から、h を求めることができます。
(43)
7.4.7 変換の順序
変換の合成は行列の積で表されますが、行列の積は交換の法則が成り立ちません。したがって、
同じ変換行列を合成した場合でも、その順序が異なれば、合成変換の結果は異なります。図 86 の 例では、正方形を回転してから x 軸方向に引き伸ばすとひし形になりますが、x 軸方向に引き伸 ばしてから回転すると回転した長方形になります。
図 86 変換の順序による合成変換の結果の違い
void main() {
gl_Position = model * position;
}
表 5 4行4列の行列のデータ型
l メインプログラム (main.cpp) の変更点
Matrix クラスの定義を記述したヘッダファイル Matrix.h を、main.cpp の冒頭で #include しま す。
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <memory>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "Window.h"
#include "Matrix.h"
#include "Shape.h"
main() 関数では、これまで使っていたバーテックスシェーダの uniform 変数 size、scale、およ
び location の代わりに、uniform 変数 model の場所をプログラムオブジェクトから取り出します。
int main() {
《省略》
// プログラムオブジェクトを作成する
const GLuint program(loadProgram("point.vert", "point.frag"));
// uniform 変数の場所を取得する
const GLint modelLoc(glGetUniformLocation(program, "model"));
// 図形データを作成する
std::unique_ptr<const Shape> shape(new Shape(2, 4, rectangleVertex));
これまでシェーダで行っていた拡大縮小 (scale / size) を、scale() メソッドを使って変換行列に 置き換えて、Matrix 型の変数 scaling に格納します。また、position による平行移動の変換も
変数のデータ型 内容
要素のアクセス
mat4 mc; mat4 型の変数宣言
mat4 単精度浮動小数点 4 行 4 列の行列
mc[0][0] = 1.0;
mc[3] = vec4(0.0);
mc の 0 行 0 列の一つの要素に 1.0 を代入する mc の 3 行目の四つの要素に全部 0.0 を代入する
translate() メソッドを使って変換行列に置き換えて、Matrix 型の変数 translation に格納します。
この二つを乗算し、合成した変換を Matrix 型の変数 model に格納します。そして model の メンバの配列 matrix のポインタを data() メソッドで取り出して、glUniformMatrix4fv() 関数を使 ってバーテックスシェーダの uniform 変数 model に設定します。
// ウィンドウが開いている間繰り返す
while (window.shouldClose() const == GL_FALSE) {
// ウィンドウを消去する
glClear(GL_COLOR_BUFFER_BIT);
// シェーダプログラムの使用開始 glUseProgram(program);
// 拡大縮小の変換行列を求める
const GLfloat *const size(window.getSize());
const GLfloat scale(window.getScale() * 2.0f);
const Matrix scaling(Matrix::scale(scale / size[0], scale / size[1], 1.0f));
// 平行移動の変換行列を求める
const GLfloat *const position(window.getLocation());
const Matrix translation(Matrix::translate(position[0], position[1], 0.0f));
// モデル変換行列を求める
const Matrix model(translation * scaling);
// uniform 変数に値を設定する
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, model.data());
// 図形を描画する shape->draw();
// カラーバッファを入れ替えてイベントを取り出す
window.swapBuffers();
} }
n サンプルプログラム step13
void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat
*value)
現在使用中のシェーダプログラムの location に指定した index の mat4 型の uniform 変数に
GLfloat 型の配列変数 value の値を設定します。
location
値を設定する mat4 型の uniform 変数の index。
count
設定する uniform 変数が mat4 型の配列のとき、その要素数。配列でなければ 1。
transpose
配列変数を転置して格納する場合は GL_TRUE、転置しない場合は GL_FALSE。したがって、
これを GL_TRUE にすれば、配列の要素の順序を変換行列と一致させることができる (図
74 参照)。
value
設定する GLfloat 型の配列変数。mat4 型は 4 行 4 列の float 型の要素を持つ行列なので、
GLfloat 型の要素を count × 16 個もつ配列を指定する。