本文提供一個輕量級的 3D 數學庫 vmath,以 C 語言實現常用的 4x4 矩陣運算:平移、縮放、旋轉(X/Y/Z 軸)、透視投影與正交投影。採用列主序(Column-major)儲存,適合直接傳遞給 OpenGL glUniformMatrix4fv。
#ifndef _VMATH_H
#define _VMATH_H
#ifdef __cplusplus
extern "C" {
#endif
typedef float Matrix44f[16];
void translate(Matrix44f M, float x, float y, float z);
void scale(Matrix44f M, float x, float y, float z);
void rotateX(Matrix44f M, float radian);
void rotateY(Matrix44f M, float radian);
void rotateZ(Matrix44f M, float radian);
void rotateXYZ(Matrix44f M, float radian, float x, float y, float z);
void perspectiveFrustum(Matrix44f M, float left, float right,
float top, float bottom, float near, float far);
void orthoPerspect(Matrix44f M, float left, float right,
float top, float bottom, float near, float far);
#ifdef __cplusplus
}
#endif
#endif
void translate(Matrix44f M, float x, float y, float z) {
for (int i=0; i<16; i++) M[i]=0;
M[3]=x; M[7]=y; M[11]=z; M[15]=1.0;
}
void scale(Matrix44f M, float x, float y, float z) {
for (int i=0; i<16; i++) M[i]=0;
M[0]=x; M[5]=y; M[10]=z; M[15]=1.0;
}
void rotateX(Matrix44f M, float rad) {
for (int i=0; i<16; i++) M[i]=0;
M[0]=1; M[5]=cos(rad); M[6]=sin(rad);
M[9]=-sin(rad); M[10]=cos(rad); M[15]=1;
}
// rotateY, rotateZ 同理...
void perspectiveFrustum(Matrix44f M, float l, float r,
float t, float b, float n, float f) {
for (int i=0; i<16; i++) M[i]=0;
M[0] = 2*n/(r-l);
M[2] = (r+l)/(r-l);
M[5] = 2*n/(t-b);
M[6] = (t+b)/(t-b);
M[10] = (n+f)/(n-f);
M[11] = 2*n*f/(n-f);
M[14] = -1;
}
void orthoPerspect(Matrix44f M, float l, float r,
float t, float b, float n, float f) {
for (int i=0; i<16; i++) M[i]=0;
M[0] = 2/(r-l); M[3] = (l+r)/(l-r);
M[5] = 2/(t-b); M[7] = (b+t)/(b-t);
M[10] = 2/(n-f); M[11] = (n+f)/(f-n);
M[15] = 1;
}
Matrix44f proj, view, model, mvp;
perspectiveFrustum(proj, -1, 1, 1, -1, 1, 100);
translate(view, 0, 0, -5);
rotateY(model, 0.5f);
// mvp = proj * view * model (需自行實現矩陣乘法)
glUniformMatrix4fv(loc, 1, GL_TRUE, mvp);
gcc -c vmath.c -o vmath.o
ar rcs libvmath.a vmath.o
# 專案中連結 -lvmath
作者提供 VC++2008 編譯好的靜態庫下載。註:rotateXYZ(繞任意軸旋轉)尚未實作。
| 0 | 1 | 2 | 3 | |
|---|---|---|---|---|
| 0 | M[0] | M[4] | M[8] | M[12] |
| 1 | M[1] | M[5] | M[9] | M[13] |
| 2 | M[2] | M[6] | M[10] | M[14] |
| 3 | M[3] | M[7] | M[11] | M[15] |
平移分量位於 M[12], M[13], M[14](即第 4 行),符合 OpenGL 慣例。