Lighthouse3d.com >> GLUT Tutorial >> Basics >> Resizing the Window

上一章的例子创建了两个窗体,命令行窗体和OpenGL窗体.当改变窗体大小的时候,高宽比例改变,三角形就会扭曲.得到这样的效果的原因是我们没设置正确的视觉.视觉默认是声明宽高比为1并依此来绘图.所以当比例改变的时候,视觉会发生扭曲.因此,每次比例改变的时候视觉必须要重新计算.

GLUT提供了一个回调接口给窗体大小改变事件.此外,该函数在窗体初始化创建的时候也会被调用,所以即便你初始化的窗体不是正方形看上去也不会有问题.原型如下:

void glutReshapeFunc(void (*func)(int width, int height));

func - 指向的函数名,就是该接口要绑定哪个函数作为窗体大小改变事件的响应函数.

我们要做的是在main函数中添加这个的实现代码.加入后main函数如下:

int main(int argc, char **argv) {

    // init GLUT and create window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(,);
glutInitWindowSize(,);
glutCreateWindow("Lighthouse3D- GLUT Tutorial"); // register callbacks
glutDisplayFunc(renderScene); // Here is our new entry in the main function
glutReshapeFunc(changeSize); // enter GLUT event processing cycle
glutMainLoop(); return ;
}

下一步要做的是定义函数来自适应视觉.glutReshapeFunchan函数有两个参数,这两个参数就是新的宽和高,视觉上的,是窗体的客户区域,不包括窗体边框.

void changeSize(int w, int h) {

    // Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == )
h = ;
float ratio = 1.0* w / h; // Use the Projection Matrix
glMatrixMode(GL_PROJECTION); // Reset Matrix
glLoadIdentity(); // Set the viewport to be the entire window
glViewport(, , w, h); // Set the correct perspective.
gluPerspective(,ratio,,); // Get Back to the Modelview
glMatrixMode(GL_MODELVIEW);
}

第一步是先计算宽高比,注意窗体的高为0要做容错处理.

我们把当前矩阵转换成投影矩阵.这样做是为了确定可视的体积.然后我们读取单位矩阵来初始化它.再往后,我们利用glViewport函数把视口设置成全窗体.你可以试一下不同的值,看出来什么效果.前两个参数是左下角的坐标,后两个参数是视口的宽高.注意坐标是和客户区域有关,而不是屏幕.如果你用不同值来试,记得要用新的宽高来计算比例.

gluPerspective函数是OpenGL的另一个库,OpenGL工具库或者GLU. GLU是一个实现OpenGL的标准组件.

gluPerspective函数包含创建视觉的参数.第一个参数定义了可视角度域的yz平面,ratio参数定义了视口的宽高比关系.后面两个参数定义远近的切面.介乎于最近值和最远值之间的所有东西都会从场景中减掉.设置了以上参数后,你就会什么都看不见了.

最后,我们告知OpenGL所有矩阵操作都会用到模型视觉矩阵.这会用在安全边上.例如设置镜头和透明对象会用到该矩阵.最佳方案是保持模型视觉矩阵在默认值.

完整代码如下:

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif void changeSize(int w, int h) { // Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if (h == )
h = ; float ratio = w * 1.0 / h; // Use the Projection Matrix
glMatrixMode(GL_PROJECTION); // Reset Matrix
glLoadIdentity(); // Set the viewport to be the entire window
glViewport(, , w, h); // Set the correct perspective.
gluPerspective(,ratio,,); // Get Back to the Modelview
glMatrixMode(GL_MODELVIEW);
} void renderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBegin(GL_TRIANGLES);
glVertex3f(-,-,-5.0);
glVertex3f(,0.0,-5.0);
glVertex3f(0.0,,-5.0);
glEnd(); glutSwapBuffers();
} int main(int argc, char **argv) { // init GLUT and create window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(,);
glutInitWindowSize(,);
glutCreateWindow("Lighthouse3D - GLUT Tutorial"); // register callbacks
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize); // enter GLUT event processing loop
glutMainLoop(); return ;
}

[译]GLUT教程 - 改变窗体大小的更多相关文章

  1. [译]GLUT教程(目录)

    http://www.lighthouse3d.com/tutorials/glut-tutorial/ GLUT是OpenGL Utility Toolkit的意思.作者Mark J. Kilgar ...

  2. WPF实现无边框窗体拖拽右下角▲ 改变窗体大小【framwork4.0】 谢谢大家关注

    效果图:(右下角拖拽改变窗体大小) 第一步:添加xaml代码: <Border Name="ResizeBottomRight" MouseMove="Resize ...

  3. windows sdk编程禁止改变窗体大小

    #include <windows.h> /*消息处理函数声明*/ HRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM ...

  4. [译]GLUT教程 - 重整子窗体

    Lighthouse3d.com >> GLUT Tutorial >> Subwindows >> Reshape Subwindows 重整函数的回调需要处理两 ...

  5. [译]GLUT教程 - 初始化

    Lighthouse3d.com >> GLUT Tutorial >> Basics >> Initialization 这一节开始从main函数入手.第一步是线 ...

  6. [译]GLUT教程 - 创建和关闭子窗体

    Lighthouse3d.com >> GLUT Tutorial >> Subwindows >> Creating and Destroying Subwind ...

  7. [译]GLUT教程 - 渲染到子窗体

    Lighthouse3d.com >> GLUT Tutorial >> Subwindows >> Rendering to Subwindows 先回顾一下之前 ...

  8. [译]GLUT教程 - 游戏模式

    Lighthouse3d.com >> GLUT Tutorial >> Extras >> Game Mode 根据GLUT官网的说明,GLUT的游戏模式是为开启 ...

  9. [译]GLUT教程 - 键盘

    Lighthouse3d.com >> GLUT Tutorial >> Input >> Keyboard GLUT可以让应用程序自动监测键盘输入,包括普通按键和 ...

随机推荐

  1. 洛谷——P2862 [USACO06JAN]把牛Corral the Cows

    P2862 [USACO06JAN]把牛Corral the Cows 题目描述 Farmer John wishes to build a corral for his cows. Being fi ...

  2. 【bzoj4318】【OSU!】期望dp——维护多个期望值递推

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=62369739 Description osu 是 ...

  3. linux-后台运行程序-nohup

    语法格式: nohup 命令 &                     (日志输出到当前目录nohup.out) nohup 命令 & >> 文件         (日志 ...

  4. SQL SERVER 内存学习系列

    http://www.cnblogs.com/double-K/p/5049417.html http://blog.sina.com.cn/s/blog_5deb2f5301014wti.html ...

  5. VUE -- Mac上解决Chrome浏览器跨域问题

    最近做前端开发总是遇到一个很奇怪的现象,同一个AJAX请求,在Chrome里调试的时候就会提示跨域,但是在手机模拟器或者真机上调试的时候就不会,于是百度了一下,发现是Chrome的安全策略导致的,需要 ...

  6. 新人补钙系列教程之:3D理论 - 二进制空间分割(BSP)树

    1. 什么是BSP树 BSP算法的初始数据是一个多边形集,BSP在预处理的时候先在多边形集中选取一个多边形作为支持平面,然后根据这个平面将集合划分成两个部分,每个部分是一个新的子节点,递归进行该过程, ...

  7. ~/.bash_profile介绍

    mac和linux终端一般用bash来进行解析.当bash在读完了整体环境变量的/etc/profile并借此调用其他配置文件后,接下来则是会读取用户自定义的个人配置文件.bash读取的文件总共有三种 ...

  8. Unity载入和内存管理机制

    Unity几种动态载入Prefab方式的差异: 事实上存在3种载入prefab的方式: 一是静态引用,建一个public的变量,在Inspector里把prefab拉上去,用的时候instantiat ...

  9. PHP面试题遇到的几个坑。...面壁ing

    1.指针悬挂问题 $array = [1, 2, 3]; echo implode(',', $array), "\n"; foreach ($array as &$val ...

  10. Weblogic OutOfMemory exception的误解 -- thread limitation

    不是全部的OutofMemory exception都是内存问题... 前几天有个客户的site报了下面错误: [ERROR][thread ] Could not start thread Time ...