OpenGL中viewport和 scissor test的问题

本文探讨了OpenGL中视口(viewport)变换和scissor test的作用。视口将归一化后的几何体映射到屏幕空间,而scissor test则在片元着色阶段后限制了处理的像素范围。通过示例代码展示了当调整视口大小和启用scissor test时,如何影响屏幕上的渲染效果。

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

注意一下:

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

这里视口变换是将归一化、裁剪之后的那个单位立方体内的几何体坐标变换到了屏幕空间坐标系,所谓视口,也就是以屏幕坐标系指定的一个矩形区域,它在我们所创建的窗口之内,参考原点就在窗口的左下角,之所以说是屏幕空间坐标系(很明显,屏幕是二维的啊),是因为我们在这里还保存了针对顶点的深度信息(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; 
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值