標頭檔 (vmath.h)
#ifndef _VMATH_H
#define _VMATH_H
#ifdef __cplusplus
extern "C" {
#endif
typedef float Matrix44f[16]; // 列主序 (OpenGL 相容)
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
實作檔 (vmath.c)
#include
#include
#include
#include "vmath.h"
static inline void mat44_identity(Matrix44f M) {
memset(M, 0, 16 * sizeof(float));
M[0] = M[5] = M[10] = M[15] = 1.0f;
}
void translate(Matrix44f M, float x, float y, float z) {
mat44_identity(M);
M[12] = x; M[13] = y; M[14] = z; // 列主序:第 4 列為平移
}
void scale(Matrix44f M, float x, float y, float z) {
mat44_identity(M);
M[0] = x; M[5] = y; M[10] = z;
}
void rotateX(Matrix44f M, float rad) {
mat44_identity(M);
float c = cosf(rad), s = sinf(rad);
M[5] = c; M[6] = s;
M[9] = -s; M[10] = c;
}
void rotateY(Matrix44f M, float rad) {
mat44_identity(M);
float c = cosf(rad), s = sinf(rad);
M[0] = c; M[2] = -s;
M[8] = s; M[10] = c;
}
void rotateZ(Matrix44f M, float rad) {
mat44_identity(M);
float c = cosf(rad), s = sinf(rad);
M[0] = c; M[1] = -s;
M[4] = s; M[5] = c;
}
void perspectiveFrustum(Matrix44f M, float l, float r, float t, float b, float n, float f) {
memset(M, 0, 16 * sizeof(float));
M[0] = 2*n/(r-l); M[4] = 0; M[8] = (r+l)/(r-l); M[12] = 0;
M[1] = 0; M[5] = 2*n/(t-b); M[9] = (t+b)/(t-b); M[13] = 0;
M[2] = 0; M[6] = 0; M[10] = (f+n)/(n-f); M[14] = 2*f*n/(n-f);
M[3] = 0; M[7] = 0; M[11] = -1; M[15] = 0;
}
void orthoPerspect(Matrix44f M, float l, float r, float t, float b, float n, float f) {
memset(M, 0, 16 * sizeof(float));
M[0] = 2/(r-l); M[4] = 0; M[8] = 0; M[12] = -(r+l)/(r-l);
M[1] = 0; M[5] = 2/(t-b); M[9] = 0; M[13] = -(t+b)/(t-b);
M[2] = 0; M[6] = 0; M[10] = -2/(f-n); M[14] = -(f+n)/(f-n);
M[3] = 0; M[7] = 0; M[11] = 0; M[15] = 1;
}
矩陣佈局說明 (列主序 Column-Major)
索引: 0 4 8 12
1 5 9 13
2 6 10 14
3 7 11 15
OpenGL glUniformMatrix4fv(..., GL_FALSE, M) 期望列主序。
平移分量位於 M[12], M[13], M[14]。
使用範例
Matrix44f model, view, proj, mvp;
translate(model, 1.0f, 2.0f, -5.0f);
rotateY(model, 0.5f);
scale(model, 2.0f, 2.0f, 2.0f);
perspectiveFrustum(proj, -1, 1, -1, 1, 1, 100);
// mvp = proj * view * model (需自行實作矩陣乘法)
待補充功能
rotateXYZ:羅德里格斯旋轉公式實現任意軸旋轉
mat44_mul、mat44_inverse、mat44_transpose
- 向量運算 (點積、叉積、正規化)
- 四元數 (Quaternion) 支援球面線性插值 (SLERP)
- SIMD 優化 (SSE/AVX/NEON)
編譯靜態庫
gcc -c vmath.c -o vmath.o -O2 -march=native
ar rcs libvmath.a vmath.o
# 使用:gcc main.c -lvmath -L.