openGL如何在改变窗口大小时,使自己的图形不被拉伸

这里要注意两个概念:视口和视景体,当视口的纵横比和视景体的纵横比相同的时候,改变窗口大小,图像才不会变形;

视景体是指成像景物所在空间的集合。它是一个空间集合体。

单个的视景体,比如一个球体,若要完全显示,其视景体应该是该球体的最小外接立方体;若要只显示上半部分,则取上半球,其视景体是上半球的最小外接立方体。对于半球而言,上半球是视景体,那么其只有上半球有显示权限,下半球没有,所以就算是将该球体位置拉远,也只能看到上半球。

若视景体仅仅为上半球,那么默认情况下,上半球所映射的画布刚好充满摄像机。将摄像机下移,则摄像机画面中显示的是上半球切面的水平线,水平线以下是黑色背景色。即使此时从理论上来说摄像机对着下半球,但由于视景体仅为上半球,所以下半球是没有显示权限的,是不会被显示的。

对OpenGL而言,视景体就意味着可显示空间,在该空间内的一切物体都可以被显示,都可以被看到,该空间外的一切物体都不能被看到。相机若要看到该空间中的物体,则相机本身就必须处于该视景体空间中。若相机在视景体空间外,哪怕该视景体就在相机正对的面前,相机依然无法看到

例如:
控制视口大小为:glViewprot(0,0,400,200);则其纵横比为2
那么控制视景体的参数为:gluPerspective(fovy,2,near,far);可以了

添加代码如下:

 1 void changeSize(GLsizei w, GLsizei h)
 2 {
 3     if (h == 0)
 4         h = 1;
 5     glViewport(0, 0, w, h);
 6     glMatrixMode(GL_PROJECTION);
 7     glLoadIdentity();
 8
 9     if (w <= h)
10     {
11         glOrtho(0.0f, 300.0f, 0.0f, 300.0f * h / w, 1.0f, -1.0f);
12     }
13     else
14     {
15         glOrtho(0.0f, 300.0f * w / h, 0.0f, 300.0f, 1.0f, -1.0f);
16     }
17
18     glMatrixMode(GL_MODELVIEW);
19     glLoadIdentity();
20 }

注意:绘制图形时需要使用像素坐标系,左下角为原点。例如:glRectf(100.0f, 100.0f, 200.0f, 200.0f); 而不是glRectf(-0.5f, -0.5f, 0.5f, 0.5f);

原文地址:https://www.cnblogs.com/keguniang/p/9857975.html

时间: 2024-10-28 12:45:20

openGL如何在改变窗口大小时,使自己的图形不被拉伸的相关文章

PyQt通过resize改变窗体大小时ListWidget显示异常

前几天开始的pygame音乐播放器Doco,做的差不多了,上午做到了歌词显示和搜索页面.遇到bug,即通过resize改变ui大小时ListWidget显示异常 #目的: 增加一部分窗口用来显示歌词和搜索页面.也就是在原来播放器的基础上通过resize增加窗口宽度,然后增加相应的内容. #test 由于Doco代码过于臃肿,笔者来一个test来描述上午遇到的问题吧. 首先,欲改变ui宽度,则想到resize Test.resize(852, 714) #设置高和宽 Test.setFixedSi

OpenGL一: 初始化窗口,简单画图

好久没搞OpenGL了,图形学的理论学的多,看来也需要多多动手做图形学软件,实际多做点东西出来才行. 因为理论书看了很多,但是一直没有太大的突破了,整个游戏是如何做成的,整个引擎怎么做出来的,基本所有相关技术我都了解,对我来说一点都不神秘,但是还是差那么一点点,觉得自己还没有达到专业水准. 感觉那么一点点就是个坎,一直跨不过去,好,这次一定要跨越它! 至于理论书看了多少本,我自己都忘记了,单单说大部头的纯英文书,都超过十几本吧. 这回少看理论了,而由简单的程序开始,下苦功夫,手打上百个程序再说,

VC++环境下单文档SDI与OpenGL多视图分割窗口的实现-类似3DMAX的主界面

本文主要讲述如何在VC++环境下实现单文档SDI与OpenGL多视图分割窗口,最终的界面类似3DMAX的主界面.首先给出我实现的效果图: 整个实现过程网络上有很多零散的博文,请各位自行搜索,在基于对话框.单文档或多文档下实现多视图分割窗口的原理是一致的.本文检索了众多相关论文,发现了几篇写的非常细致的论文.在此向相关作者表示感谢.下面给出龚勋的论文原文,大家可以仔细阅读和学习.相信一定能够做出来想要的效果的.但是文中对于全局变量的定义和初始化在VC++2015环境下编译不通过.经过排查,发现这些

matplotlib 设置图形大小时 figsize 与 dpi 的关系

matplotlib 中设置图形大小的语句如下: fig = plt.figure(figsize=(a, b), dpi=dpi) 其中: figsize 设置图形的大小,a 为图形的宽, b 为图形的高,单位为英寸 dpi 为设置图形每英寸的点数 则此时图形的像素为: px, py = a*dpi, b*dpi # pixels # e.g. # 6.4 inches * 100 dpi = 640 pixels 也就是说,同一像素尺寸的图形(比如 1200 * 600)可以有任意种不同的组

容器改变/窗口改变重新渲染echarts

是否遇见使用侧边栏菜单收缩/展开,echarts容器大小变化,但是echarts不重新自适应容器.或者,window窗口改变但是echarts不随着改变,针对这两种echarts不自适应的情况,分享下自己处理方法. 方法核心是:监听使echarts容器大小发生变化的因素及window窗口改变去调用echarts实例的resize()方法.(方法以VUE框架代码为示例) 一:为什么不能自适应:   ECharts没有绑定resize事件,显示区域大小发生改变内部并不知道,在容器大小发生改变时需要手

表格内,设置许多元素的大小时,js的速度慢的办法

因为要做可编辑的表格,生成的表格结构如下: <td class=" autoEdit" data-field="sex">      <input class="autoEditinput" value="1" data-url="1111"  data-field="sex"> </td> 我要的最终效果是:(粉色的是input) 但input与表格

修改SharePoint网站最大上载大小时有时需要关注的事项

我们在用SharePoint存储文档时,用户要上传200多MB到站点上,结果受到上传大小限制.在管理中心里做了修改,增加了上载大小限制.可是用户在上传的时候,不是提示连接超时,就是未知错误.结果查了下,微软的支持中心里找到了原因,有些情况下,要想真正实现能够上传大文件,还要注意以下情况. 由于网络传输速度的原因,一个大文件,可能要传很长时间.这个我们可能在虚机里或者本地局域网里觉察不出来速度太慢的情况.一个文件没有传完,就出现了超时的情况. 要解决此问题,请使用一个或多个以下的方法: l 修改管

拖拽边缘改变窗口(物体)大小

<body> <div id="div1"></div></body> <style> #div1 {width: 100px; height: 100px; background: red; position: absolute; left: 500px; top: 200px;} </style> <script> window.onload = function() { var oDiv = do

显示图像实际大小时使用滚动条

视图类的基类是CView不支持滚动条,要把CView改为CScrollView.共有三步以实现: void CMyAppView::OnInitialUpdate() { CScrollView::OnInitialUpdate(); CSize sizeTotal; sizeTotal.cx = sizeTotal.cy = 600; //看不到滚动条把数值加大 SetScrollSizes(MM_TEXT, sizeTotal); } (3)把MyAppView.h和MyAppView.cp