http://anony3721.blog.163.com/blog/static/51197420114282720194/

OpenGL Glut剖析(2)--平行投影及其显示范围

2011-05-02 22:11:46|  分类: 默认分类 |  标签:opengl  |字号 订阅

首先强调一个看似废话的概念:OpenGL中无论是平行投影还是透视投影,只有位于视景体中的物体才能被看到,即显示到窗口显示区。

这个概念很基础同样很重要,网上几乎没有人愿意解释此概念。但是初学者的程序出现“黑屏”往往是由于对此概念没有理解。OpenGL提供了两种基本类型的投影,1、透视投影:远大近小;2、正投影(平行投影):不影响相对大小,一般用于建筑和CAD应用程序中。

(一)glOrtho平行投影下,如何将物体显示在窗口区域上?

glOrtho是创建一个正交平行的视景体。一般用于物体不会因为离屏幕的远近而产生大小的变换的情况。比如,常用的工程中的制图等。这里不讲glOrtho的函数详细说明,用实例说话!不懂的读者请参考我的博客其他文章或自己Google。

1. glOrtho平行投影下,二维物体的显示情况

结论:①平行投影下,要将物体现实在屏幕上只要将物体放置在glOrtho创建的视景体中即可。

②glutInitWindowSize窗口中所现实的仅仅是该平行视景体的成比例缩放的像。也就是说不可能通过改变glutInitWindowSize的尺寸而看到原来看不到的物体。

OpenGL中世界窗口以当前显示窗口中心为原点,水平向右为+x轴,竖直向上为+y轴,垂直于屏幕指向我们为+z轴。长度单位这样来定:平面窗口范围按此单位恰好是左下角(-1,-1) 到右上角(1,1)。OpenGL默认的glOrtho创建的平行视景体就是这种情况。

1)First 程序及运行结果

将下面代码中的橙色部分代码加上对显示结果没有影响,证明OpenGL glut中的默认平行投影视景体是个(-1,-1,-1)到(1,1,1)的立方体。

#include <GL/glut.h>void display(void)
{glClear (GL_COLOR_BUFFER_BIT); /* clear all pixels  */glColor3f (1.0, 1.0, 1.0); //设置当前绘制颜色//glTranslated(0,0,-1.1);  // 物体位于视景体之外,黑屏glTranslated(0,0,-1.0);  // 可以看到右上角的白色正方形//glTranslated(0,0,1.0); // 可以看到右上角的白色正方形//glTranslated(0,0,1.1); //物体位于视景体之外,黑屏glRectf(0.25f, 0.25f, 0.75f, 0.75f);  //可以看出位于视景体内//glRectf(1.25f, 1.25f, 1.75f, 1.75f); // 位于视景体外,所以显示不出来glFlush (); //don't wait! start processing buffered OpenGL routines
}void init (void)
{glClearColor (0.0, 0.0, 0.0, 0.0); /* select clearing olor  */
//  glMatrixMode(GL_PROJECTION); /* initialize viewing values  */
//  glLoadIdentity();
//  glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); //注意该视景体的范围和几何中心
}int main(int argc, char** argv)
{glutInit(&argc, argv);glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);glutInitWindowSize (500, 500);  //改为glutInitWindowSize (250, 250); 可以看出变换的仅仅是物体按比例大小的变换glutInitWindowPosition (100, 100);glutCreateWindow ("First");init ();glutDisplayFunc(display); glutMainLoop();return 0;
}

2)Second 程序及运行结果

#include <GL/glut.h>
void init(void)
{glClearColor (0.0, 0.0, 0.0, 0.0); /* select clearing color  */glMatrixMode(GL_PROJECTION); /* initialize viewing values  */glLoadIdentity();glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); //与上面1)的First的glOrtho 对比可以看出视景体的范围和几何中心对绘图结果的影响
}
void display(void)
{glClear(GL_COLOR_BUFFER_BIT);glRectf(0.25f, 0.25f, 0.75f, 0.75f);  //注意正方形的几何中心在(0.5,0.5)glFlush();
}
int main(int argc, char **argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize(250, 250);   //glutInitWindowSize (500, 500); //可以看出物体的比例没变,仅仅是大小的改变glutInitWindowPosition(100, 100);glutCreateWindow(argv[0]);init();glutDisplayFunc(display);glutMainLoop();return 0;
}

2. glOrtho平行投影下,三维物体的显示情况

1) 半径为1的球体默认的显示

将下面代码中的橙色部分代码加上对显示结果没有影响,证明OpenGL glut中的默认投影是个平行投影,并且平行投影视景体是个(-1,-1,-1)到(1,1,1)的立方体。

#include <GL/glut.h>
void init(void)
{glClearColor(0.0, 0.0, 0.0, 0.0);
//  glMatrixMode(GL_PROJECTION); /* initialize viewing values  */
//  glLoadIdentity();
//  glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); //注意该视景体的范围和几何中心
}
void display(void)
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//glTranslatef(0,0,-1.0); //向-z方向移动1个单位后,球显示的尺寸没变,因球心移到视景体的后平面//glTranslatef(0,0,-1.5); // 为什么球变小了,球心移动到视景体之外,看到的是被视景体后平面截取的部分//glTranslatef(0,0,-2); //黑屏,此时球与平行视景体的后面相切//glTranslatef(0,0,1); //此时球心位于平行视景体的"前面"//glTranslatef(0,0,1.5); //此时球心位于平行视景体的"前面",结果与glTranslatef(0,0,-1.5)相同//glTranslatef(0,0,2); //黑屏,此时球与平行视景体的前面相切glutSolidSphere(1.0, 20, 16); //半径为1的球体glFlush();
}
int main(int argc, char **argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize(500, 500); //换成glutInitWindowSize(300, 300);对比下结果glutInitWindowPosition(100, 100);glutCreateWindow("a 3D Shpere with radius = 1");init();glutDisplayFunc(display);glutMainLoop();return 0;
}

 //由上图物体的显示可以看出,视景体的大小和中心位置。

 glutSolidSphere是GLUT工具包中的一个函数 该函数用于渲染一个球体。球体球心位于原点。在OpenGL中默认的原点就是窗口客户区的中心。 函数原型 void glutSolidSphere(GLdouble radius , GLint slices , GLint stacks); void glutWireSphere(GLdouble radius, GLint slices, GLint stacks ); radius 球体的半径 slices 围绕在Z轴周围的细小部分的数量(类似于地球上经线把地球表面分成的一块块“细小部分”) stacks 沿y轴分布的细小部分的数量(类似于纬线) 一般而言, 后两个参数赋予较大的值, 渲染花费的时间要长, 效果更逼真。

2) glOrtho设置平行视景体的范围和大小对物体显示的影响-----视景体的范围在(-1,-1,-1)~(1,1,1)

#include <GL/glut.h>void init(void)
{glClear (GL_COLOR_BUFFER_BIT);// glClearColor(0.0, 0.0, 0.0, 0.0);glMatrixMode(GL_PROJECTION); /* initialize viewing values  */glLoadIdentity();glOrtho(0.0, 1.0, 0.0, -1.0, -1.0, 1.0);  //注意y的范围应该是bottom < top,这里说明bottom和top都用的绝对值
}void display(void)
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);/*注意该视景体的范围和几何中心glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);  // in the first quadrantglOrtho(-1.0, 0.0, 0.0, 1.0, -1.0, 1.0);  // in the second quadrantglOrtho(-1.0, 0.0, -1.0, 0.0, -1.0, 1.0);  // in the third quadrantglOrtho(0.0, 1.0, -1.0, 0.0, -1.0, 1.0); // in the fourth quadrantglOrtho(0.0, 1.0, 0.0, -1.0, -1.0, 1.0);  //注意y的范围应该是bottom < top,这里说明bottom和top都用的绝对值
*/glutSolidSphere(1.0, 20, 16); //glFlush();
}
int main(int argc, char **argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize(500, 500);glutInitWindowPosition(100, 100);glutCreateWindow("a 3D Shpere with radius = 1");init();glutDisplayFunc(display);glutMainLoop();return 0;
}



3)视景体的范围对物体显示的影响---------视景体的范围超出(-1,-1,-1)~(1,1,1)
#include <GL/glut.h>
void init(void)
{glClearColor(0.0, 0.0, 0.0, 0.0);glMatrixMode(GL_PROJECTION); /* initialize viewing values  */glLoadIdentity();glOrtho(-2.0, 2.0, -2.0, 2.0, -1.0, 1.0); //注意该视景体的范围和几何中心
}
void display(void)
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glutSolidSphere(1.0, 20, 16); //半径为1的球体glFlush();
}int main(int argc, char **argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize(500, 500); //换成glutInitWindowSize(300, 300);对比下结果glutInitWindowPosition(100, 100);glutCreateWindow("a 3D Shpere with radius = 1");init();glutDisplayFunc(display);glutMainLoop();return 0;
}



(二)glutInitWindowSize对物体显示的影响

实际上glutInitWindowSize的大小对物体在显示区域中显示的大小是有影响的,如下代码中所示。前边说OpenGL中显示物体仅仅需要将物体放在视景体中是为了让大家抓住主要矛盾。其实物体的最终形状还与显示屏中窗口区域的大小有关。要在一个非正方形的窗口内现实出“正球”此时就涉及到一个纵横比锁定的问题。

1) 纵横比不等于1的窗口下“单位球”的显示
int main(int argc, char **argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize(500, 200);glutInitWindowPosition(100, 100);glutCreateWindow("a 3D Shpere with radius = 1");init();glutDisplayFunc(display);glutMainLoop();return 0;
}



2)通过将平行投影视景体的纵横比设置为显示窗口的纵横比校正窗口的纵横比不为一所带来的影响
#include <GL/glut.h>
void init(void)
{int aspectRatio;aspectRatio = 500/200;glClearColor(0.0, 0.0, 0.0, 0.0);glMatrixMode(GL_PROJECTION); /* initialize viewing values  */glLoadIdentity();// glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); //注意该视景体的范围和几何中心glOrtho(-1.0*aspectRatio, 1.0*aspectRatio, -1.0, 1.0, -1.0, 1.0); // w > h
}
void display(void)
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glutSolidSphere(1.0, 20, 16); //半径为1的球体glFlush();
}
int main(int argc, char **argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize(500, 200); glutInitWindowPosition(100, 100);glutCreateWindow("aspect ration not equal to 1");init();glutDisplayFunc(display);glutMainLoop();return 0;
}


OpenGL Glut剖析(2)--平行投影及其显示范围相关推荐

  1. OpenGL(glut)模拟太阳系:太阳,地球,月球,火星

    GitHub项目地址OpenGL(glut)模拟太阳系:太阳,地球,月球,火星 核心代码如下: // orgin.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并 ...

  2. Ubuntu下安装OpenGL/Glut库

    http://www.libaqiang.com/?p=78330 1.Ubuntu下安装OpenGL/Glut库 OpenGL(全写Open Graphics Library)是个定义了一个跨编程语 ...

  3. 基于C++和OpenGL (GLUT) 实现太阳系行星系统

    基于C++和OpenGL (GLUT) 实现太阳系行星系统 效果图: 分析与设计 OpenGL 包含了很多渲染函数,但是他们的设计目的是独立于任何窗口系统或操作系统的.因此,它自身并没有包含创建打开窗 ...

  4. 如何在Python中创建OpenGL/Glut

    OpenGL(开放图形库)是一种跨语言.多平台的应用程序编程接口(API),用于绘制二维和三维计算机图形. API通常用于与图形处理单元(GPU)交互,以实现硬件加速渲染.OpenGL由Silicon ...

  5. OpenGL模板 Mac Cmake OpenGL(Glut) Template

    自己经常使用的一些功能做一个模板,有灯光效果,你可以用鼠标放大,围绕所述旋转坐标系的原点 Main.cpp #include <GLUT/glut.h> #include <cstd ...

  6. eclipse opengl java_eclipse openGL glut运行环境配置

    eclipse_opengl_glut_setting opengl一般使用vs来开发,我个人还是偏向使用eclipse,这里是eclipse使用glut的配置 首先下载glut包,包含下面5个文件: ...

  7. ubuntu配置openGL glut库

    openGL开发有比较好用的库:glut,本文讲述ubuntu该如何配置: 以下为安装过程(需要root权限): 1. apt-get install build-essential 2. apt-g ...

  8. OpenGL Glut 初学

    第一个代码:绘制一个凸多边形,更改背景和多边形的颜色 #include <GL/glut.h> #include<iostream> using namespace std; ...

  9. VS2019 OpenGL glut:错误: 无法打开包括文件:“gl/glut.h”: No such file or directory

    罪魁祸首 更新了vs2019 解决方法 在更新之后,vs2019的安装目录下(我装在C盘)C:\Program Files (x86)\Microsoft Visual Studio\2019\Pro ...

最新文章

  1. vue中Axios的封装与API接口的管理详解
  2. 图像处理opencv(一)
  3. Java调用webservice.asmx接口.
  4. python mysql删除数据_python-mysql删除和更新数据
  5. Moment.js常见用法总结 1
  6. Go实现Raft第三篇:命令和日志复制
  7. 解决Ubuntu Chrome浏览器很卡不响应的问题
  8. 是什么让它3年融资破4亿?神策背后的探索与巨变
  9. size ar objdump readelf binutils
  10. IEEE_Tec_Digtal Signal Analog Signal
  11. 网卡bonding配置
  12. 智慧城市是如何用大数据建成的?
  13. 第6期:大学生应该选择哪种主流编程语言
  14. 远程控制计算机无法粘贴,Windwos服务器远程桌面不能复制粘贴的解决方法
  15. 【Python】Talk Python To Me Podcast播客
  16. 【7gyy】cdma无线通讯上使用的技术
  17. 【JZOJ A组】Melancholy
  18. CISCO 基于时间访问控制
  19. 测绘资质分级标准-工程测量、界线与不动产测绘
  20. linux软件的下载

热门文章

  1. 商品期货人数(期货品种数量)
  2. 你会找什么样的男朋友!
  3. 计算机图形学研究软件
  4. 安装SQL2000,提示安装程序配置服务器失败。
  5. ORBSLAM3中的MLPnP在重定位时计算当前帧和候选帧的位姿变换
  6. aiwi体感游戏,感受聊斋风情
  7. JAVA判断上传文件后缀名是否符合规范MultipartFile
  8. 欧拉线性筛法求素数(顺便实现欧拉函数的求值)
  9. 不积跬步无以至千里002
  10. Android的APPT工具会优化PNG吗?