一 视点变换
相机位置(视点)的变换
void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,
GLdouble centerx,GLdouble centery, GLdouble centerz ,
GLdouble upx,GLdouble upy,GLdouble upz)
二 模型变换
模型位置的变化
1 平移
glTranslate{fd}(TYPE x,TYPE y,TYPE z);
2 旋转
glRotate{fd}(TYPE angle,TYPE x,TYPE,y,TYPE z);
3 缩放
glScale{fd}(TYPE x,TYPE y,TYPE z);
三 投影变换
将三维模型投影到屏幕上显示。
1 透视投影
离视点近的物体大,离视点远的物体小,远到极点即为消失,成为灭点。
void glFrustum(GLdouble left,GLdouble Right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);
void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear, GLdouble zFar);
2 正视投影
无论物体距离相机多远,投影后的物体大小尺寸不变,正投影相当于在无限远处观察得到的结果。
void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top, GLdouble near,GLdouble far);
void gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top);
四 视口变换
将视景体内投影的物体显示在二维的视口平面上。
glViewport(GLint x,GLint y,GLsizei width, GLsizei height);
五 裁剪变换
除了视景体定义的六个裁剪平面外,还可自定义一个或多个附加裁剪平面,以去掉场景中无关的目标。
void glClipPlane(GLenum plane,Const GLdouble *equation);
六 太阳地球月球示例
#include <glut.h> #include <stdio.h> #include <time.h> static int day = 200; double getFPS() { static int count; static double save; static clock_t last, current; double timegap; ++count; if (count <= 50){ return save; } count = 0; last = current; current = clock(); timegap = (current-last)/(double)CLK_TCK; save = 50.0f / timegap; return save; } void display() { // 打印FPS double FPS = getFPS(); printf("FPS = %f\n", FPS); glEnable(GL_DEPTH_TEST);// 开启更新深度缓冲区的功能,被挡住的像素不绘制 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 清除颜色缓冲|深度缓冲 glMatrixMode(GL_PROJECTION);// 设置当前矩阵模式:对投影矩阵应用随后的矩阵操作 glLoadIdentity(); //将之前矩阵变换导致变化过的栈顶矩阵重新归位,置为单位矩阵,即之前的矩阵变换带来的影响到此为止 gluPerspective(75, 1, 1, 400000);// 设置透视投影矩阵 glMatrixMode(GL_MODELVIEW);// 设置当前矩阵模式:对模型视景矩阵堆栈应用随后的矩阵操作. glLoadIdentity();//将之前矩阵变换导致变化过的栈顶矩阵重新归位,置为单位矩阵,即之前的矩阵变换带来的影响到此为止 gluLookAt(0, -200000, 200000, 0, 0, 0, 0, 0, 1);// 设置视点 //sun glColor3f(1, 0, 0);// 设置绘制颜色为红色 glutSolidSphere(69600, 20, 20);// 渲染一个球体 // earth glColor3f(0, 0, 1);// 设置绘制颜色为蓝色 glRotatef(day, 0, 0, -1);// 旋转 glTranslatef(150000, 0, 0);// 平移 glutSolidSphere(15945, 20, 20);// 渲染一个球体 //moon glColor3f(1, 1, 0); glRotatef(day / 30.0 * 360 - day, 0, 0, -1);// 旋转 glTranslatef(38000, 0, 0);// 平移 glutSolidSphere(4345, 20, 20);// 渲染一个球体 glFlush();// 清空缓冲区,立即执行绘制命令 glutSwapBuffers();// 双缓冲时交换两个缓冲区指针 } void idle() { ++day; if (day > 360){ day = 0; } display();// 调用display方法进行强制刷新 } int main(int argc, char **argv) { glutInit(&argc, argv);// 初始化GLUT glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);// 显示显示模式(RGB颜色|双缓冲) glutCreateWindow("earth,moon,sun");// 设置窗口标题 glutInitWindowSize(400, 400);// 设置窗口大小 glutDisplayFunc(display);// 设置绘制函数 glutIdleFunc(&idle); glutMainLoop();// 开启消息循环 return 0; }