顶点变换的步骤:
视图与模型变换一起组成了模型视图矩阵,这个矩阵作用于物体坐标,产生视觉坐标。紧接着,如果指定了其他的裁剪平面,用于从场景中删除某些物体或者提供物体的裁剪视图,这些裁剪平面会在这个时候生效。之后,OpenGL使用投影矩阵产生了裁剪坐标。这个变换定义了一个视景体,位于这个空间外的物体将会被裁剪掉。随后发生的是透视除法,它把坐标除以w,产生规范化的设备坐标。最后,经过变换的坐标经过视口变换成为窗口坐标。可以通过控制视口的大小对最终的图像进行放大、缩小和拉伸(cocos2dx的屏幕适配原理)。
绘制立方体的例子:
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glLoadIdentity();
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glScalef(1.0, 2.0, 1.0);
glutWireCube(1.0);
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode(GL_MODELVIEW);
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
}
int main(int argc, char * argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(500, 500);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(&display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
glLoadIdentity():把当前矩阵设置为单位矩阵,通过加载单位矩阵来清除当前矩阵。
diaplay()函数包括了模型和视图变换,以及绘制的函数,需要重复调用,用于绘制窗口的内容。
reshape()函数在窗口变化时指定投影变换。
- 视图变换:
视图变换相当于调整摄像机的位置和朝向。glLookAt指定了视图变换,如例子所示摄像机在(0, 0, 5)位置,镜头朝向(0, 0, 0),朝上向量指定为(0, 1, 0)。总体的效果就是把镜头向z轴的方向拉远了5个单位,便于看到绘制的立方体。
- 模型变换:
模型变换是为了调整物体的位置和方向,通常模型和视图变换组合成模型视图矩阵。display函数中就包含了模型和视图变换,因为需要重复调用满足绘制的需求,在窗口移动或遮挡时需要调用,所以需要加载单位矩阵。
- 投影变换:
投影变换相当于给摄像机选择镜头。在窗口创建,移动或改变形状时会调用reshape函数。
- 视口变换:
视口变换相当于最终经过处理的照片的大小和位置,例如照片是否需要放大和缩小,投影变换和视口变换决定了场景如何映射到屏幕上。
视图和模型变换
- 全局固定坐标系:如果采用全局固定的坐标系来作为参考,在这种坐标系中,矩阵乘法就会模型的位置、方向和缩放,就必须要注意乘法出现的顺序和在代码中出现的顺序相反。
- 局部移动坐标系:乘法出现的顺序和在代码中出现的顺序相同。
模型视图矩阵堆栈可以包含至少32个4x4的矩阵,而且一开始的顶部矩阵是单位矩阵。
投影变换
* 透视投影:平截头体;
* 正投影:正交平行视景体。
一般情况下投影矩阵堆栈的深度只有2层。常见的应用在显示包含帮助的文本窗口的时候,在正投影的模式下比较容易定位,可以暂时把投影模式设为正投影,然后再返回原来的透视投影模式。
视口变换
1、定义视口;
2、变换深度坐标。
版权声明:本文为博主原创文章,未经博主允许不得转载。