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上的 投影变换.

 

posted @ 2013-10-25 21:54  Dai Hanlong  阅读(173)  评论(0)    收藏  举报