OpenGL技术之View Volume, Viewport, Screen的关系
一、View Volume
View Volume,有时候叫做View Frustum,也就是视景体。这个东西是定义了我们能够通过虚拟的3D摄像机所能看到的场景。当我们在一个3D场景中站立的时候,除了我们的位置之外,同样需要视野来定义我们所能够看到的东西。而这个视野就是通过视景体来定义的。一般在3D中,我们有两种不同的方式定义视景体。他们的形状分别如下所示:
1.jpg
图1
2.jpg
图2
上面给出了两个不同的视景体,图1表示的是中心透视视景体,而图2表示的是正交投影视景体。这两个几何体都全面的定义了我们所能够看到的视野,在OpenGL中也分别有不同的指令对应与这两个几何体。
我们都知道,在3D图形学中,我们是通过定义投影矩阵的方式来描述视景体的。通过定义中心透视矩阵来描述中心透视视景体,通过定义正交矩阵的方式来定义正交视景体。
4.png
二、Viewport
Viewport,中文翻译为视口。它的定义具有两个意义。一个意义是它定义了上面定义的视景体中的景物将会绘制到一张什么尺寸的画布之上,另外一个意义表示这个绘制好的图像将会被显示在屏幕的什么区域。
很明显,如果我们定义的视景体的投影平面的宽高比和视口所定义的宽高比不相同的话,那么将视景体中的物体绘制到画布上的时候会进行拉伸或者压缩;而当视景体投影平面的宽高比和视口所定义的宽高比一致的时候,图像将会不进行任何缩放绘制到视口所定义的画布之上。
视口定义中还包含了这个视口所表示的图像将会被绘制到屏幕的哪块区域之上的信息。在很多的图形应用中,我们都会发现在一个窗口中绘制多个3D场景的情况。而这个技术就是通过定义多个视口,绘制多个图像,然后“贴在”一个比较大的屏幕的多个不同的区域。
三、Screen
Screen即屏幕的意思,在真实世界中,我们都是通过屏幕上的东西来观察3D世界的。所有的场景最终都要被光栅化成为我们显示器上的图像。也就是说屏幕是3D场景的最终输出目的地。一个Screen可以容纳显示多个视口中的内容。
四、三者的关系
通过前面的介绍,我们大致的了解了这三个不同东西的概念。从中我们可以知道,通过定义投影矩阵,我们实际上是在虚拟的3D空间中,创建了一个视野,也就是视景体。在接着,我们通过定义视口,来描述视景体中的内容如何映射到一个虚拟的画布之上,并且这个画布最终将显示在屏幕上的什么位置。当所有的这些都设置完毕,我们绘制完毕场景之后,就能够通过硬件在我们的显示器屏幕上看到最终的画面。更理论的表述就是,通过定义投影矩阵,将3D场景投影到一个投影平面之上。通过定义视口,我们将投影平面上的内容映射到这个视口中去,并且填满它,同时根据定义视口是给定的屏幕坐标的位置,将这个视口中的图像映射到窗口的指定位置之上,最终我们就看到了图像。
#ifndef GLUT_DISABLE_ATEXIT_HACK
#define GLUT_DISABLE_ATEXIT_HACK
#endif
#include
#include
#include
void oglDisplay();
int main()
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowSize(400,400);
glutCreateWindow(“Viewport”);
glutDisplayFunc(oglDisplay);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glutMainLoop();
return 0;
}
void oglDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
// Left-Bottom
glViewport(0,0, 200, 200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-100.0f, 100.0f, -100.0f, 100.0f, 100.0f, -100.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glRectf(-100.0f, 100.0f, 100.0f, -100.0f);
// Right-Bottom
glViewport(200, 0, 200, 200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-100.0f, 100.0f, -100.0f, 100.0f, 100.0f, -100.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glRectf(-100.0f, 100.0f, 100.0f, -100.0f);
// Left-Top
glViewport(0, 200, 200, 200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-100.0f, 100.0f, -100.0f, 100.0f, 100.0f, -100.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glRectf(-100.0f, 100.0f, 100.0f, -100.0f);
// Right-Top
glViewport(200, 200, 200, 200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-100.0f, 100.0f, -100.0f, 100.0f, 100.0f, -100.0f);
glColor3f(1.0f, 1.0f, 0.0f);
glRectf(-100.0f, 100.0f, 100.0f, -100.0f);
glFlush();
}
3.jpg
WEBGL学习网 » OpenGL技术之View Volume, Viewport, Screen的关系