相关主题:OpenGL 渲染管线,OpenGL 投影矩阵,OpenGL矩阵类
下载:matrixModelView.zip,matrixProjection.zip
// 注意对象首先被平移,然后被旋转 glRotatef(angle, 1, 0, 0); // 将对象绕x轴旋转angle角度 glTranslatef(x, y, z); // 移动对象到(x,y,z)处 drawObject();
// 这创建了一个对称的截头锥 // 它将给定的4个参数(fovy, aspect, near, far)转换 // 成glFrustum()所需的6个参数:(l, r, b, t, n, f) void makeFrustum(double fovY, double aspectRatio, double front, double back) { const double DEG2RAD = 3.14159265 / 180; double tangent = tan(fovY/2 * DEG2RAD); // fovY的一半的正切,fovY是视线的夹角 double height = front * tangent; // 近裁剪面的高度的一半 double width = height * aspectRatio; // 近裁剪面的宽度的一半 // params: left, right, bottom, top, near, far glFrustum(-width, width, -height, height, front, back); }然而,如果你需要创建一个不对称的视景体那么必须直接使用glFrustum()函数。例如,如果你需要渲染一个宽屏场景到两个邻接的屏幕中,你可以将视景体划分成两个不对称的视景体(左边和右边),然后将场景分别渲染到两个视景体中,如下图:
// 将纹理绕x轴旋转 glMatrixMode(GL_TEXTURE); glRotatef(angle, 1, 0, 0);
注意无论在Mac下还是在Windows下所有的OpenGL函数调用都是在ModelGL.h和ModelGL.cpp中实现的,在两个包中所有文件都是相同的。
这个例子程序使用一个自定义的4*4矩阵类和OpenGL默认的矩阵模式来指定模型变换和视图变换。ModelGL.cpp中定义了3个矩阵对象:matrxModel,matrixView和matrixModelView。每个矩阵存储了前乘的变换并使用glLoadMatrix()函数将矩阵中的元素传递到OpenGL中。实际的绘图模式如下:
... glPushMatrix(); // 为视图变换设置视图矩阵 glLoadMatrixf(matrixView.getTranspose()); // 在模型变换之前绘制最原始的网格 drawGrid(); // 为模型变换和视图变换设置模型视图矩阵 // 从物体坐标系变换到人眼坐标系 glLoadMatrixf(matrixModelView.getTranspose()); // 模型视图变换之后绘制一个茶壶 drawTeapot(); glPopMatrix(); ...
... glPushMatrix(); // 将模型视图矩阵归一化 glLoadIdentity(); // 首先,将视图从物体坐标系变换到人眼坐标系 // 注意所有的值都是负数,因为我们是使用视图矩阵的逆来移动整个场景 glRotatef(-cameraAngle[2], 0, 0, 1); // roll glRotatef(-cameraAngle[1], 0, 1, 0); // heading glRotatef(-cameraAngle[0], 1, 0, 0); // pitch glTranslatef(-cameraPosition[0], -cameraPosition[1], -cameraPosition[2]); // 在模型变换之前绘制最原始的网格 drawGrid(); // 模型变换 // GL_MODELVIEW矩阵的结果如下: // ModelView_M = View_M * Model_M glTranslatef(modelPosition[0], modelPosition[1], modelPosition[2]); glRotatef(modelAngle[0], 1, 0, 0); glRotatef(modelAngle[1], 0, 1, 0); glRotatef(modelAngle[2], 0, 0, 1); // 模型视图变换之后绘制一个茶壶 drawTeapot(); glPopMatrix(); ...
这个例子程序显示了如何使用glFrustum()函数和glOrtho()函数来操作投影变换。
下载源代码和可执行程序:matrixProjection.zipmatrixProjection_mac.zip(OS X 10.6+)
再次说明,ModelGL.h和ModelGL.cpp在Window和Mac下是一样的,并且所有的OpenGL函数调用都在这两个文件中。
ModelGL类有一个自定义的矩阵对象,matrixProjection,和两个成员函数,setFrustum()和setOrthoFrustum(),这两个函数等价于glFrustum()和glOrtho()。
/////////////////////////////////////////////////////////////////////////////// // 使用6个参数像glFrustum()函数一样设置一个透视的视景体 // (left, right, bottom, top, near, far) // 注意:这是以行为主的标记方式,OpenGL需要先将其转置 /////////////////////////////////////////////////////////////////////////////// void ModelGL::setFrustum(float l, float r, float b, float t, float n, float f) { matrixProjection.identity(); matrixProjection[0] = 2 * n / (r - l); matrixProjection[2] = (r + l) / (r - l); matrixProjection[5] = 2 * n / (t - b); matrixProjection[6] = (t + b) / (t - b); matrixProjection[10] = -(f + n) / (f - n); matrixProjection[11] = -(2 * f * n) / (f - n); matrixProjection[14] = -1; matrixProjection[15] = 0; } /////////////////////////////////////////////////////////////////////////////// // 使用6个参数像glOrtho()函数一样设置一个正投影的视景体 // (left, right, bottom, top, near, far) // 注意:这是以行为主的标记方式,OpenGL需要先将其转置 /////////////////////////////////////////////////////////////////////////////// void ModelGL::setOrthoFrustum(float l, float r, float b, float t, float n, float f) { matrixProjection.identity(); matrixProjection[0] = 2 / (r - l); matrixProjection[3] = -(r + l) / (r - l); matrixProjection[5] = 2 / (t - b); matrixProjection[7] = -(t + b) / (t - b); matrixProjection[10] = -2 / (f - n); matrixProjection[11] = -(f + n) / (f - n); } ... // 将投影矩阵传递给OpenGL glMatrixMode(GL_PROJECTION); glLoadMatrixf(matrixProjection.getTranspose()); ...构造一个16个元素的GL_PROJECTION矩阵可以参考这儿。