glViewport()函数和glOrtho()函数的理解

   

OpenGL中有两个比较重要的投影变换函数,glViewport和glOrtho.

glOrtho是创建一个正交平行的视景体。
一般用于物体不会因为离屏幕的远近而产生大小的变换的情况。比如,常用的工程中的制图等。需要比较精确的显示。 而作为它的对立情况,
glFrustum则产生一个透视投影。这是一种模拟真是生活中,人们视野观测物体的真实情况。例如:观察两条平行的火车到,在过了很远之后,这两条铁轨是会相交于一处的。还有,离眼睛近的物体看起来大一些,远的物体看起来小一些。

glOrtho(left, right, bottom, top, near, far),
left表示视景体左面的坐标,right表示右面的坐标,bottom表示下面的,top表示上面的。这个函数简单理解起来,就是一个物体摆在那里,你怎么去截取他。这里,我们先抛开glViewport函数不看。先单独理解glOrtho的功能。
假设有一个球体,半径为1,圆心在(0, 0, 0),那么,我们设定glOrtho(-1.5, 1.5, -1.5, 1.5, -10,
10);就表示用一个宽高都是3的框框把这个球体整个都装了进来。  如果设定glOrtho(0.0,
1.5, -1.5, 1.5, -10, 10);就表示用一个宽是1.5,
高是3的框框把整个球体的右面装进来;如果设定glOrtho(0.0, 1.5, 0.0, 1.5, -10,
10);就表示用一个宽和高都是1.5的框框把球体的右上角装了进来。上述三种情况可以见图:

从上述三种情况,我们可以大致了解glOrtho函数的用法。

---glViewport():

glOrtho函数只是负责使用什么样的视景体来截取图像,并不负责使用某种规则把图像呈现在屏幕上。

glViewport主要完成这样的功能。它负责把视景体截取的图像按照怎样的高和宽显示到屏幕上。

比如:如果我们使用glut库建立一个窗体:glutInitWindowSize(500, 500);
然后使用glutReshapeFunc(reshape); reshape代码如下:

void reshape(int width, int height)

{

glViewport(0, 0, (GLsizei)width, (GLsizei)height);

glMatrixModel(GL_PROJECTION);

glLoadIdentity();

glOrtho(-1.5, 1.5, -1.5, 1.5, -10, 10);

....

}

这样是可以看到一个正常的球体的。但是,如果我们创建窗体时glutInitWindowSize(800,
500),那么看到的图像就是变形的。上述情况见图。

因为我们是用一个正方形截面的视景体截取的图像,但是拉伸到屏幕上显示的时候,就变成了glViewport(0, 0, 800,
500);也就是显示屏变宽了,
倒是显示的时候把一个正方形的图像“活生生的给拉宽了”。就会产生变形。这样,就需要我们调整我们的OpenGL显示屏了。我们可以不用800那么宽,因为我们是用的正方形的视景体,所以虽然窗体是800宽,但是我们只用其中的500就够了。修改一下程序。

void reshape(int width, int height)

{

int dis =
width < height ? width : height;

glViewport(0, 0, dis,
dis);

glMatrixModel(GL_PROJECTION);

glLoadIdentity();

glOrtho(-1.5, 1.5, -1.5, 1.5, -10, 10);

.....

}

另外,关于glViewport()函数,我们还可以用来调整图像的分辨率。例如,保持目前的窗体大小不变,我们如果用这个size来只显示整个物体的一部分,那么图像的分辨率就必然会增大。例如:

void reshape(int w, int h)

{

glViewport(0, 0, (GLsizei)w, (GLsizei)h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

if (w
<= h)

glOrtho(0, 1.5, 0, 1.5 * (GLfloat)h/(GLfloat)w, -10.0,
10.0);

else

glOrtho(0, 1.5*(GLfloat)w/(GLfloat)h, 0, 1.5, -10.0,
10.0);

}

可以把分辨率扩大4倍。

而如果再修改一下glViewport(0, 0, 2 * (GLsizei)w, 2 * (GLsizei)h);
则可以把分辨率扩大16倍。

完整的测试程序:

#include <GL/gl.h>

#include <GL/glu.h>

#include <GL/glut.h>

void init(void)

{

GLfloat
mat_specular[] = {1.0, 1.0, 1.0, 1.0};

GLfloat
mat_shininess[] = {50.0};

GLfloat
light_position[] = {1.0, 1.0f, 1.0, 0.0};

GLfloat
white_light[] = {1.0, 1.0, 1.0, 1.0};

GLfloat
lmodel_ambient[] = {0.1, 0.1, 0.1, 1.0};

glClearColor(0.0, 0.0, 0.0, 0.0);

glShadeModel(GL_SMOOTH);

glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

glLightfv(GL_LIGHT0, GL_POSITION, light_position);

glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);

glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);

glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);

glEnable(GL_LIGHTING);

glEnable(GL_LIGHT0);

glEnable(GL_DEPTH_TEST);

}

void display(void)

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glutSolidSphere(1.0, 20, 16);

glFlush();

}

void reshape(int w, int h)

{

glViewport(0, 0, (GLsizei)w, (GLsizei)h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

if (w
<= h)

glOrtho(-1.5, 1.5, -1.5 * (GLfloat)h/(GLfloat)w, 1.5 *
(GLfloat)h/(GLfloat)w, -10.0, 10.0);

else

glOrtho(-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h,
-1.5, 1.5, -10.0, 10.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

int main(int argc, char **argv)

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);

glutInitWindowSize(500, 500);

glutInitWindowPosition(100, 100);

glutCreateWindow(argv[0]);

init();

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutMainLoop();

return
0;

}

PROJECT(s5)

CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

ADD_EXECUTABLE(s5 main.cpp)

FIND_PACKAGE(OpenGL)

FIND_PACKAGE(GLUT)

IF(OPENGL_FOUND)

INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})

TARGET_LINK_LIBRARIES(${PROJECT_NAME}
${OPENGL_LIBRARIES})

ELSE(OPENGL_FOUND)

MESSAGE(FATAL_ERROR "OpenGL not
found")

ENDIF(OPENGL_FOUND)

IF(GLUT_FOUND)

INCLUDE_DIRECTORIES(${GLUT_INCLUDE_DIR})

TARGET_LINK_LIBRARIES(${PROJECT_NAME}
${GLUT_LIBRARIES})

ELSE(GLUT_FOUND)

ENDIF(GLUT_FOUND)

glViewport()函数和glOrtho()函数的理解的更多相关文章

  1. glViewport()函数和glOrtho()函数的理解(转)

    http://www.cnblogs.com/yxnchinahlj/archive/2010/10/30/1865298.html 在OpenGL中有两个比较重要的投影变换函数,glViewport ...

  2. glViewport()函数和glOrtho()函数的理解(转)

    转:http://www.cnblogs.com/yxnchinahlj/archive/2010/10/30/1865298.html 摘要:glOrtho相当指定图框的大小,由此会使得图框里的图形 ...

  3. 深入理解javascript函数定义与函数作用域

    最近在学习javascript的函数,函数是javascript的一等对象,想要学好javascript,就必须深刻理解函数.本人把思路整理成文章,一是为了加深自己函数的理解,二是给读者提供学习的途径 ...

  4. Lua函数以及闭合函数的理解

    Lua函数以及闭合函数的理解 来源 http://blog.csdn.net/mydad353193052/article/details/48731467 词法域和第一类型 在C/C++,C#或者J ...

  5. typedef void (*Fun) (void) 的理解——函数指针——typedef函数指针

    首先介绍大家比较熟悉的typedef int i;//定义一个整型变量i typedef myInt int: myInt j;//定义一个整型变量j 上面介绍得是我们常用的比较简单的typedef的 ...

  6. 深入理解,函数声明、函数表达式、匿名函数、立即执行函数、window.onload的区别.

    一.函数声明.函数表达式.匿名函数1.函数声明:function fnName () {…};使用function关键字声明一个函数,再指定一个函数名,叫函数声明. 2.函数表达式 var fnNam ...

  7. 理解JavaScript普通函数以及箭头函数里使用的this

    this 普通函数的this 普通函数的this是由动态作用域决定,它总指向于它的直接调用者.具体可以分为以下四项: this总是指向它的直接调用者, 例如 obj.func() ,那么func()里 ...

  8. Python关于函数作为返回值的理解(3分钟就看完了)

    话不多说,直接看例子,上代码: def line_conf(): def line(x): return 2 * x + 1 return line #return a function object ...

  9. Sigmoid函数与Softmax函数的理解

    1. Sigmod 函数 1.1 函数性质以及优点 其实logistic函数也就是经常说的sigmoid函数,它的几何形状也就是一条sigmoid曲线(S型曲线).               其中z ...

随机推荐

  1. [Apache Doris] Apache Doris 元数据设计及DDL操作源码阅读

    元数据设计 如上图,Doris 的元数据主要存储4类数据: 用户数据信息.包括数据库.表的 Schema.分片信息等. 各类作业信息.如导入作业,Clone 作业.SchemaChange 作业等. ...

  2. C#窗体学习

    //进度条控件 private void button1_Click(object sender, EventArgs e)        {            int i;            ...

  3. [luogu7476]苦涩

    维护线段树,在其每一个节点上维护一个set(可重),以及子树内所有set的最大值 考虑下传标记,如果将所有元素全部下传复杂度显然不正确,但注意到我们仅关心于其中的最大值,即仅需要将最大值下传即可 其有 ...

  4. Dubbo的反序列化安全问题——kryo和fst

    目录 0 前言 1 Dubbo的协议设计 2 Dubbo中的kryo序列化协议触发点 3 Dubbo中的fst序列化协议触发点 3.1 fst复现 3. 2 思路梳理 4 总结 0 前言 本篇是Dub ...

  5. Cortex-A系列中断

    1. 回顾STM32系统 1.1 中断向量表 ARM芯片冲0x00000000,在程序开始的地方存放中断向量表,按下中断时,就相当于告诉CPU进入的函数.描述很多个中断服务函数的表. 对于STM32来 ...

  6. Python实战:截图识别文字,过万使用量版本!(附源码!!)

    前人栽树后人乘凉,以不造轮子为由 使用百度的图片识字功能,实现了一个上万次使用量的脚本. 系统:win10 Python版本:python3.8.6 pycharm版本:pycharm 2021.1. ...

  7. 获取客户端Mac地址

    近期有个需求,需要获取客户端Mac地址作为白名单验证的依据.使用.net,B/S架构.先百度找了一些获取mac地址的方法, using System; using System.Collections ...

  8. vue简单语法梳理

    小图不够清楚,可以点击大图查看.

  9. Codeforces 407E - k-d-sequence(单调栈+扫描线+线段树)

    Codeforces 题面传送门 & 洛谷题面传送门 深感自己线段树学得不扎实-- 首先特判掉 \(d=0\) 的情况,显然这种情况下满足条件的区间 \([l,r]\) 中的数必须相同,双针扫 ...

  10. Atcoder Grand Contest 015 F - Kenus the Ancient Greek(找性质+乱搞)

    洛谷题面传送门 & Atcoder 题面传送门 一道难度 Au 的 AGC F,虽然看过题解之后感觉并不复杂,但放在现场确实挺有挑战性的. 首先第一问很简单,只要每次尽量让"辗转相除 ...