OpenGL中viewport和 scissor test的问题

来源:互联网 发布:关键词诊断优化 编辑:程序博客网 时间:2024/06/04 08:04

初看之下,在视口变换之后,几何体应该显示在屏幕窗体的范围已经确定了。

注意一下:

世界坐标系->观察坐标系->投影变换->归一化、裁剪->视口变换

这里视口变换是将归一化、裁剪之后的那个单位立方体内的几何体坐标变换到了屏幕空间坐标系,所谓视口,也就是以屏幕坐标系指定的一个矩形区域,它在我们所创建的窗口之内,参考原点就在窗口的左下角,之所以说是屏幕空间坐标系(很明显,屏幕是二维的啊),是因为我们在这里还保存了针对顶点的深度信息(z向坐标)。这个过程可以发现的是,裁剪之后,变换到视口区域内的几何体信息,丢掉的是处在裁剪立方体之外的顶点信息。

而事实上,顶点信息和像素信息是有区别的。顶点信息存储在顶点缓冲区,而像素信息是在帧缓冲区里面的。比如我们要是定义一个点的SIZE很大,占据了10个像素的话,从顶点信息来判断,它是处在视口之内的,但是在转换成像素的时候,却又有像素点超出了视口范围(它管不了)。

scissor在片元着色阶段之后,处理的就是像素信息,它所划定的一块矩形区域,就是最终的像素信息所被限定的范围。可以推断的是,当我们不对这个矩形域作限制的时候,我们所能管理的像素区域就是整个的窗口。所以像glClear()之类的直接处理帧缓冲区的函数作用的像素范围就是整个窗口,并不受视口限制。只有当我们的限制了scissor test之后,我们的所处理的像素范围也被限制起来了。

可以用下面的代码测试一下
#include<GL/freeglut.h>
void init(){
glClearColor(0.0, 1.0, 0.0, 1.0);//这样每次调用glClear清除颜色缓冲区的时候,就会清成这种颜色
glEnable(GL_SCISSOR_TEST);
}
void OnDisplay(){
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 1.0);
glRectf(-25.0, -25.0, 25.0, 25.0);
glutSwapBuffers();
}
void OnReshape(int w, int h){
gluOrtho2D(-50.0, 50.0, -50.0, 50.0);
/*glViewport(0, 0, w, h);*///第一种情况,视口和窗口一致,看不出问题
glViewport(0, 0, w / 2, h / 2);//第二种情况,视口变成窗口1/4,发现绘制的矩形变小了,但是整个窗口仍然被clear成绿色
glScissor(0, 0, w / 2, h / 2);//你会发现窗口被清理成绿色的部分变小了
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(OnDisplay);
glutReshapeFunc(OnReshape);
glutMainLoop();
return 0; 
}

0 0
原创粉丝点击