OpenGL-创建视口

问题描述:
之前我们创建了一个简单的窗口。但是存在这一个问题,我们创建窗口的时候创建了一个正方形,在窗口中绘制一个正方形,所以窗口中的正方形可以正常显示。(如下图)

这里写图片描述

但是当我们拉伸窗口,将窗口变为长方形的时候,发现图形中的正方形也跟着变成了长方形。(如下图)

这里写图片描述


这并不是我们想要的结果,我们希望无论窗口怎么变化,绘制的图形都不会改变。下面我们就想想为什么拉伸窗口时图形会变形?

这个画布的大小可以和窗口大小相等,也可以不相等。在上面提到的情况就是画布大小和窗口的大小相等的情况,所以正方形发生了形变。那么,如果我们可以在窗口变化之后,仍然保持画布是一个正方形,那么我们画的内容就不会形变了。

OpenGL为我们提供了一个设置这个“画布”(视口)大小的函数,即为void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
其中x,y表示视口(画布)左下角的坐标,width,height表示视口(画布)的宽和高。注意,这里的视口左下角坐标(0,0)对应的是窗口的左下角,x轴正方向向右,y轴正方向向上。


我们在原来程序的基础上增加一个回调函数:

glutReshapeFunc(redraw);

并实现void redraw(int x, int y)函数。

void redraw(int x, int y)
{
int dis = x > y ? y : x;
glViewport(0, 0, dis, dis); //创建一个视口
}

这里我们用临时变量dis记录变换窗口的较小的边,并在将视口(画布)调节成一个正方形,这样绘制的内容就不会形变了。我们用下面的两个图来说明这个过程:
这里写图片描述

我将画布设置为整个窗口大小,颜色为蓝色。可以看出来,画布的大小开始时就是窗口的大小。
接着我改变窗口大小,将它变窄,可以预测到画布被修改为一个以窗口较窄边为长度的正方形。如下图:
这里写图片描述
图中的蓝色部分就是新的画布大小,而灰色是窗口中没有用的部分。因此在这个蓝色部分中所绘制的正方形还是正方形。

源码如下:

/*
*OpenGL学习02
*程序功能:在之前的基础上添加视口,可以改变窗口的大小
*/

#include <gl\glut.h>

void draw()
{
    glClearColor(0.6, 0.6, 0.6, 0.0); 
    glClear(GL_COLOR_BUFFER_BIT);
    glRectf(-0.5, -0.5, 0.5, 0.5);
    glFlush();
}

void redraw(int x, int y)
{
    int dis = x > y ? y : x;
    glViewport(0, 0, dis, dis); //创建一个视口
    /*
    *x,y表示视口左下角的坐标,width,height表示视口的宽度和高度
    *这里选择大小改变后的窗口较小的边,作为新的视口的变长
    */
}

void main()
{
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(600, 600);
    glutCreateWindow("有视口的窗口");
    glutDisplayFunc(draw);
    glutReshapeFunc(redraw);
    glutMainLoop();
}

原窗口如下图:
这里写图片描述
修改窗口后的效果如图:
这里写图片描述
可以看出绘制的正方形不会形变。


为了进一步了解glViewport函数,我们进一步修改程序。
OpenGL中我们可以通过glViewport函数,轻易的实现多窗口,即设立多个视口,并在每个视口中绘制不同的内容。

我们现在将窗口拆分成四个视口,四个视口分别的绘制一个颜色不同,大小和视口大小相等的正方形,来进一步掌握视口。

glColor3f(1.0, 1.0, 1.0);
glViewport(0, 0, 200, 200);
glRectf(-1.0, -1.0, 1.0, 1.0);

glColor3f(1.0, 0.0, 0.0);
glViewport(0, 200, 200, 200);
glRectf(-1.0, -1.0, 1.0, 1.0);

glColor3f(0.0, 1.0, 0.0);
glViewport(200, 0, 200, 200);
glRectf(-1.0, -1.0, 1.0, 1.0);

glColor3f(0.0, 0.0, 1.0);
glViewport(200, 200, 200, 200);
glRectf(-1.0, -1.0, 1.0, 1.0);

上述代码中先设置一个颜色,然后设置视口大小,再绘制正方形。因为OpenGL的坐标是:坐标原点在中心,从-1~1。所以上述代码中绘制正方形的大小是视口大小。

效果图如下:
这里写图片描述

源代码如下:

/*
*OpenGL学习02
*程序功能:在之前的基础上添加视口,可以改变窗口的大小
*/

#include <gl\glut.h>

void draw()
{
    glClearColor(0.6, 0.6, 0.6, 0.0); 
    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f(1.0, 1.0, 1.0);
    glViewport(0, 0, 200, 200);
    glRectf(-1.0, -1.0, 1.0, 1.0);

    glColor3f(1.0, 0.0, 0.0);
    glViewport(0, 200, 200, 200);
    glRectf(-1.0, -1.0, 1.0, 1.0);

    glColor3f(0.0, 1.0, 0.0);
    glViewport(200, 0, 200, 200); 
    glRectf(-1.0, -1.0, 1.0, 1.0);

    glColor3f(0.0, 0.0, 1.0);
    glViewport(200, 200, 200, 200);
    glRectf(-1.0, -1.0, 1.0, 1.0);

    glFlush();
}

void redraw(int x, int y)
{
    int dis = x > y ? y : x;
    glViewport(0, 0, dis, dis); //创建一个视口
    /*
    *x,y表示视口左下角的坐标,width,height表示视口的宽度和高度
    *这里选择大小改变后的窗口较小的边,作为新的视口的变长
    */
}

void main()
{
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(400, 400);
    glutCreateWindow("有视口的窗口");
    glutDisplayFunc(draw);
    glutReshapeFunc(redraw);
    glutMainLoop();
}

希望通过上述可以帮助理解glViewport函数。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值