行列変換の説明
Scale
汎用のスケール行列を生成
- パラメータ
x,y,z x,y,z軸各々のスケール係数
- 変換行列
Translate
変換行列を生成
- パラメータ
x,y,z 変換ベクトルのx,y,z座標
- 変換行列
Rotate
回転行列を生成
- パラメータ
angle 回転する角度
x,y,z ベクトルのx,y,z座標
x,y,z ベクトルのx,y,z座標
- 変換行列
Frustum
射影行列を生成
- パラメータ
left, right クリップ面の左右の垂直座標
bottom,top クリップ面の上下の水平座標
zNear,zFar クリップ面の奥行であるnearとfar座標
bottom,top クリップ面の上下の水平座標
zNear,zFar クリップ面の奥行であるnearとfar座標
- 変換行列
Perspective
透視射影行列の生成
- パラメータ
fovy y方向の視野を度数で指定
aspect x方向の視野を決定する縦横比(aspect ratio)を指定。
縦横比は、y(高さ)に対するx(幅)の割合。
zNear ビューアから近くのクリップ面までの距離
zFar ビューアから遠くのクリップ面までの距離
aspect x方向の視野を決定する縦横比(aspect ratio)を指定。
縦横比は、y(高さ)に対するx(幅)の割合。
zNear ビューアから近くのクリップ面までの距離
zFar ビューアから遠くのクリップ面までの距離
- 変換行列
Ortho
- パラメータ
left, right 左右の垂直のクリップ面の座標
bottom,top 上下の水平のクリップ面の座標
zNear,zFar 遠近デプスのクリップまでの距離。
面がビューアの後にある場合は,これらの値は負の数となる。
bottom,top 上下の水平のクリップ面の座標
zNear,zFar 遠近デプスのクリップまでの距離。
面がビューアの後にある場合は,これらの値は負の数となる。
- 変換行列
LookAt
- パラメータ
eyeX, eyeY, eyeZ 眼点の位置
centerX, centerY, centerZ 参照点の位置
upX, upY, upZ 上向きベクトルの方向
centerX, centerY, centerZ 参照点の位置
upX, upY, upZ 上向きベクトルの方向
- 変換行列
MultMatrixf(M); Translate(-eyeX, -eyeY, -eyeZ);
Transformソースコード
- Transform.h
#ifndef __TRANSFORM_H_
#define __TRANSFORM_H_
#include <GL/gl.h>
// vector
GLfloat sl_Amountf(const GLfloat *v);
void sl_Normalizef(GLfloat *v);
GLfloat sl_Dotf(const GLfloat v0[3], const GLfloat v1[3]);
void sl_Crossf(GLfloat result[3], const GLfloat v0[3], const GLfloat v1[3]);
// Matrix
void sl_Scalef( GLfloat *result, GLfloat sx, GLfloat sy, GLfloat sz);
void sl_Translatef( GLfloat *result, GLfloat tx, GLfloat ty, GLfloat tz);
void sl_Rotatef( GLfloat *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
void sl_MultMatrixf( GLfloat *result, GLfloat *srcA, GLfloat *srcB);
void sl_LoadIdentityf(GLfloat *result);
// ModelView
void sl_Frustumf(
GLfloat *result,
float left, float right,
float bottom, float top,
float nearZ, float farZ);
void sl_Perspectivef(
GLfloat *result,
float fovy, float aspect,
float nearZ, float farZ);
void sl_Orthof(
GLfloat *result,
float left, float right,
float bottom, float top,
float nearZ, float farZ);
void sl_LookAtf(
GLfloat *result,
float ex, float ey, float ez,
float tx, float ty, float tz,
float ux, float uy, float uz);
#endif /* __TRANSFORM_H_ */
- Transform.cpp
#include <math.h>
#include "Transform.h"
///////////////////////////////////////////////////////////////////////////////
// vector
//
GLfloat sl_Amountf(const GLfloat v[3])
{
return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
}
void sl_Normalizef(GLfloat *v)
{
GLfloat a = sl_Amountf(v);
if (a == 0.0f) {
return;
}
for (int i=0; i<3; ++i) {
v[i] /= a;
}
}
GLfloat sl_Dotf(const GLfloat v0[3], const GLfloat v1[3])
{
return v0[0]*v1[0] + v0[1]*v1[1] + v0[2]*v1[2];
}
void sl_Crossf(GLfloat result[3], const GLfloat v0[3], const GLfloat v1[3])
{
GLfloat temp[3];
temp[0] = v0[1]*v1[2] - v0[2]*v1[1];
temp[1] = v0[2]*v1[0] - v0[0]*v1[2];
temp[2] = v0[0]*v1[1] - v0[1]*v1[0];
for (int i=0; i<3; ++i) {
result[i] = temp[i];
}
}
///////////////////////////////////////////////////////////////////////////////
// Matrix
//
void sl_Scalef(
GLfloat *result,
GLfloat sx,
GLfloat sy,
GLfloat sz)
{
result[ 0] *= sx;
result[ 1] *= sx;
result[ 2] *= sx;
result[ 3] *= sx;
result[ 4] *= sy;
result[ 5] *= sy;
result[ 6] *= sy;
result[ 7] *= sy;
result[ 8] *= sz;
result[ 9] *= sz;
result[10] *= sz;
result[11] *= sz;
}
void sl_Translatef(
GLfloat *result,
GLfloat tx,
GLfloat ty,
GLfloat tz)
{
result[12] += (result[ 0] * tx + result[ 4] * ty + result[ 8] * tz);
result[13] += (result[ 1] * tx + result[ 5] * ty + result[ 9] * tz);
result[14] += (result[ 2] * tx + result[ 6] * ty + result[10] * tz);
result[15] += (result[ 3] * tx + result[ 7] * ty + result[11] * tz);
}
void sl_Rotatef(
GLfloat *result,
GLfloat angle,
GLfloat x,
GLfloat y,
GLfloat z)
{
GLfloat sinAngle, cosAngle;
GLfloat mag = sqrtf(x * x + y * y + z * z);
if (mag > 0.0f) {
GLfloat xx, yy, zz;
GLfloat xy, yz, xz;
GLfloat xs, ys, zs;
GLfloat oneMinusCos;
GLfloat rotMat[16];
x /= mag;
y /= mag;
z /= mag;
sinAngle = sinf(angle * M_PI / 180.0f);
cosAngle = cosf(angle * M_PI / 180.0f);
xx = x * x;
yy = y * y;
zz = z * z;
xy = x * y;
yz = y * z;
xz = x * z;
xs = x * sinAngle;
ys = y * sinAngle;
zs = z * sinAngle;
oneMinusCos = 1.0f - cosAngle;
rotMat[ 0] = (xx * oneMinusCos) + cosAngle;
rotMat[ 1] = (xy * oneMinusCos) + zs;
rotMat[ 2] = (xz * oneMinusCos) - ys;
rotMat[ 3] = 0.0f;
rotMat[ 4] = (xy * oneMinusCos) - zs;
rotMat[ 5] = (yy * oneMinusCos) + cosAngle;
rotMat[ 6] = (yz * oneMinusCos) + xs;
rotMat[ 7] = 0.0f;
rotMat[ 8] = (xz * oneMinusCos) + ys;
rotMat[ 9] = (yz * oneMinusCos) - xs;
rotMat[10] = (zz * oneMinusCos) + cosAngle;
rotMat[11] = 0.0f;
rotMat[12] = 0.0f;
rotMat[13] = 0.0f;
rotMat[14] = 0.0f;
rotMat[15] = 1.0f;
sl_MultMatrixf(result, result, rotMat);
}
}
void sl_MultMatrixf(
GLfloat *result,
GLfloat *srcA,
GLfloat *srcB)
{
GLfloat tmp[16];
for (int i=0; i<4; ++i) {
tmp[i*4+0] =
srcA[i*4+0] * srcB[ 0]
+ srcA[i*4+1] * srcB[ 4]
+ srcA[i*4+2] * srcB[ 8]
+ srcA[i*4+3] * srcB[12];
tmp[i*4+1] =
srcA[i*4+0] * srcB[ 1]
+ srcA[i*4+1] * srcB[ 5]
+ srcA[i*4+2] * srcB[ 9]
+ srcA[i*4+3] * srcB[13];
tmp[i*4+2] =
srcA[i*4+0] * srcB[ 2]
+ srcA[i*4+1] * srcB[ 6]
+ srcA[i*4+2] * srcB[10]
+ srcA[i*4+3] * srcB[14];
tmp[i*4+3] =
srcA[i*4+0] * srcB[ 3]
+ srcA[i*4+1] * srcB[ 7]
+ srcA[i*4+2] * srcB[11]
+ srcA[i*4+3] * srcB[15];
}
for (int i=0; i<16; ++i) {
result[i] = tmp[i];
}
}
void sl_LoadIdentityf(GLfloat *result)
{
for (int i=0; i<16; ++i) {
result[i] = 0.0f;
}
result[ 0] = 1.0f;
result[ 5] = 1.0f;
result[10] = 1.0f;
result[15] = 1.0f;
}
///////////////////////////////////////////////////////////////////////////////
// ModelView
//
void sl_Frustumf(
GLfloat *result,
float left, float right,
float bottom, float top,
float nearZ, float farZ)
{
float deltaX = right - left;
float deltaY = top - bottom;
float deltaZ = farZ - nearZ;
GLfloat frust[16];
if ( (nearZ <= 0.0f) || (farZ <= 0.0f) ||
(deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f))
return;
frust[ 0] = 2.0f * nearZ / deltaX;
frust[ 1] = frust[ 2] = frust[ 3] = 0.0f;
frust[ 5] = 2.0f * nearZ / deltaY;
frust[ 4] = frust[ 6] = frust[ 7] = 0.0f;
frust[ 8] = (right + left) / deltaX;
frust[ 9] = (top + bottom) / deltaY;
frust[10] = -(nearZ + farZ) / deltaZ;
frust[11] = -1.0f;
frust[14] = -2.0f * nearZ * farZ / deltaZ;
frust[12] = frust[13] = frust[15] = 0.0f;
//sl_MultMatrixf(result, frust, result);
sl_MultMatrixf(result, result, frust);
}
void sl_Perspectivef(
GLfloat *result,
float fovy, float aspect,
float nearZ, float farZ)
{
GLfloat frustumW, frustumH;
frustumH = tanf(fovy / 360.0f * M_PI) * nearZ;
frustumW = frustumH * aspect;
sl_Frustumf(result, -frustumW, frustumW, -frustumH, frustumH, nearZ, farZ);
}
void sl_Orthof(
GLfloat *result,
float left, float right,
float bottom, float top,
float nearZ, float farZ)
{
float deltaX = right - left;
float deltaY = top - bottom;
float deltaZ = farZ - nearZ;
GLfloat ortho[16];
if ((deltaX == 0.0f) || (deltaY = 0.0f) || (deltaZ == 0.0f))
return;
sl_LoadIdentityf(ortho);
ortho[ 0] = 2.0f / deltaX;
ortho[12] = -(right + left) / deltaX;
ortho[ 5] = 2.0f / deltaY;
ortho[13] = -(top + bottom) / deltaY;
ortho[10] = -2.0f / deltaZ;
ortho[14] = -(nearZ + farZ) / deltaZ;
//sl_MultMatrixf(result, ortho, result);
sl_MultMatrixf(result, result, ortho);
}
void sl_LookAtf(
GLfloat *result,
float ex, float ey, float ez,
float tx, float ty, float tz,
float ux, float uy, float uz)
{
GLfloat lookAt[16];
float l;
tx = ex - tx;
ty = ey - ty;
tz = ez - tz;
l = sqrtf(tx * tx + ty * ty + tz * tz);
lookAt[ 2] = tx / l;
lookAt[ 6] = ty / l;
lookAt[10] = tz / l;
tx = uy * lookAt[10] - uz * lookAt[ 6];
ty = uz * lookAt[ 2] - ux * lookAt[10];
tz = ux * lookAt[ 6] - uy * lookAt[ 2];
l = sqrtf(tx * tx + ty * ty + tz * tz);
lookAt[ 0] = tx / l;
lookAt[ 4] = ty / l;
lookAt[ 8] = tz / l;
lookAt[ 1] = lookAt[ 6] * lookAt[ 8] - lookAt[10] * lookAt[ 4];
lookAt[ 5] = lookAt[10] * lookAt[ 0] - lookAt[ 2] * lookAt[ 8];
lookAt[ 9] = lookAt[ 2] * lookAt[ 4] - lookAt[ 6] * lookAt[ 0];
lookAt[12] = -(ex * lookAt[ 0] + ey * lookAt[ 4] + ez * lookAt[ 8]);
lookAt[13] = -(ex * lookAt[ 1] + ey * lookAt[ 5] + ez * lookAt[ 9]);
lookAt[14] = -(ex * lookAt[ 2] + ey * lookAt[ 6] + ez * lookAt[10]);
lookAt[ 3] = lookAt[ 7] = lookAt[11] = 0.0f;
lookAt[15] = 1.0f;
sl_MultMatrixf(result, result, lookAt);
}
参考
- OpenGLリファレンスマニュアル
- http://nopper.tv/opengl_3_2.html
- http://marina.sys.wakayama-u.ac.jp/~tokoi/