OpenGL 学习笔记
1.OpenGL 学习笔记
OpenGL 使用的是右手坐标系,点是采用列向量的形式进行表示.
GLfloat martix[16]; 可以用来表示一个矩阵。
其中,可以让其想想成按照列来进行存放,就会组成如下顺序.
0 4 8 12
1 5 9 13
2 6 10 14
3 7 11 15
Opengl 就是一个将3D画面显示在2D坐标平面上的过程.
3D中,都是实实在在的物体,每个物体都有自己的位置。
对于物体来讲,每个物体都有自己的一个坐标系,称为 本地坐标系。
物体放置在场景中,就相当于放置在一个全局的坐标系里面,这个坐标系称为 全局坐标系。
但是对于观察者来讲,看到的场景都是用过眼睛进行观察的,所以,渲染出来的画面,最好是以观察者眼睛所在
的地方进行设置坐标系,将这个坐标系称为 相机坐标系.
那么,如何计算物体在相机坐标系里面的位置?
计算的方式为: 先将 本地坐标系 变换为 世界坐标系,然后再将世界坐标系变换 到 相机坐标系.
即对于一个点 p; 变换后的 p' 为:
p' = M2*M1*p;
其中 M1表示 本地坐标系 变换为 世界坐标系 的矩阵,这里M1一般为 物体的 平移 缩放 旋转 变换
M2表示 世界坐标系变换 到 相机坐标系 的矩阵
M2(世界坐标->变换为相机坐标)矩阵的计算方式:(需要知道怎么推导过来的)
一般使用UVN相机系统.
cocos2dx里面计算 将世界坐标变换为相机坐标的矩阵 matrixLookup 的方法为:
/**
* Builds a translation matrix in the same way as gluLookAt()
* the resulting matrix is stored in pOut. pOut is returned.
*/
kmMat4* const kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye,
const kmVec3* pCenter, const kmVec3* pUp)
{
kmVec3 f, up, s, u;
kmMat4 translate;
kmVec3Subtract(&f, pCenter, pEye);
kmVec3Normalize(&f, &f);
kmVec3Assign(&up, pUp);
kmVec3Normalize(&up, &up);
kmVec3Cross(&s, &f, &up);
kmVec3Normalize(&s, &s);
kmVec3Cross(&u, &s, &f);
kmVec3Normalize(&s, &s);
kmMat4Identity(pOut);
pOut->mat[0] = s.x;
pOut->mat[4] = s.y;
pOut->mat[8] = s.z;
pOut->mat[1] = u.x;
pOut->mat[5] = u.y;
pOut->mat[9] = u.z;
pOut->mat[2] = -f.x;
pOut->mat[6] = -f.y;
pOut->mat[10] = -f.z;
kmMat4Translation(&translate, -pEye->x, -pEye->y, -pEye->z);
kmMat4Multiply(pOut, pOut, &translate);
return pOut;
}
其中返回值就是 matrixLookup;
但是变换后,依然是3D的,要将其变为2D,就需要进行投影。
通过一个投影矩阵,将3D场景 投影到一个2D的视平面中.(省略裁剪 光照 测试等)
那么,如何计算这个投影矩阵?
OpenGL投影矩阵公式(需要知道公式怎么推导的)

其中 N表示近裁剪平面的位置,F表示远裁剪平面的位置(即z坐标)
cocos2dx里面,构造矩阵的方法:
kmMat4* const kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY,
kmScalar aspect, kmScalar zNear,
kmScalar zFar)
{
kmScalar r = kmDegreesToRadians(fovY / 2);
kmScalar deltaZ = zFar - zNear;
kmScalar s = sin(r);
kmScalar cotangent = 0;
if (deltaZ == 0 || s == 0 || aspect == 0) {
return NULL;
}
//cos(r) / sin(r) = cot(r)
cotangent = cos(r) / s;
kmMat4Identity(pOut);
pOut->mat[0] = cotangent / aspect;
pOut->mat[5] = cotangent;
pOut->mat[10] = -(zFar + zNear) / deltaZ;
pOut->mat[11] = -1;
pOut->mat[14] = -2 * zNear * zFar / deltaZ;
pOut->mat[15] = 0;
return pOut;
}
那么,一个点p变换为最终的p'的过程为:
p' = M3 * M2 * M1 * p;
其中M1表示物体的平移、缩放、旋转
M2表示将世界坐标系到相机坐标系的变换
M3表示将3D场景投影到2D上的 投影变换.

浙公网安备 33010602011771号