[译]GLUT教程 - 改变窗体大小
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教程 - 改变窗体大小的更多相关文章
- [译]GLUT教程(目录)
http://www.lighthouse3d.com/tutorials/glut-tutorial/ GLUT是OpenGL Utility Toolkit的意思.作者Mark J. Kilgar ...
- WPF实现无边框窗体拖拽右下角▲ 改变窗体大小【framwork4.0】 谢谢大家关注
效果图:(右下角拖拽改变窗体大小) 第一步:添加xaml代码: <Border Name="ResizeBottomRight" MouseMove="Resize ...
- windows sdk编程禁止改变窗体大小
#include <windows.h> /*消息处理函数声明*/ HRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM ...
- [译]GLUT教程 - 重整子窗体
Lighthouse3d.com >> GLUT Tutorial >> Subwindows >> Reshape Subwindows 重整函数的回调需要处理两 ...
- [译]GLUT教程 - 初始化
Lighthouse3d.com >> GLUT Tutorial >> Basics >> Initialization 这一节开始从main函数入手.第一步是线 ...
- [译]GLUT教程 - 创建和关闭子窗体
Lighthouse3d.com >> GLUT Tutorial >> Subwindows >> Creating and Destroying Subwind ...
- [译]GLUT教程 - 渲染到子窗体
Lighthouse3d.com >> GLUT Tutorial >> Subwindows >> Rendering to Subwindows 先回顾一下之前 ...
- [译]GLUT教程 - 游戏模式
Lighthouse3d.com >> GLUT Tutorial >> Extras >> Game Mode 根据GLUT官网的说明,GLUT的游戏模式是为开启 ...
- [译]GLUT教程 - 键盘
Lighthouse3d.com >> GLUT Tutorial >> Input >> Keyboard GLUT可以让应用程序自动监测键盘输入,包括普通按键和 ...
随机推荐
- uva11107(后缀数组)
uva11107 题意 输入 n 个 DNA 序列,求出长度最大的字符串,使得它在超过一半的 DNA 序列中连续出现.如果有多解,按字典序输出. 分析 论文 后缀数组经典题.加深几个关键数组的印象. ...
- PDF笔记:内嵌字体
前几天投文章的时候,把docx文件保存为PDF提交.但是格式检查始终在报一个关于“font embed”的错误,意思是PDF文件中有些字体没有内嵌. 为了减小文件大小,WORD保存为PDF的时候默认不 ...
- 数学【p2613】 【模板】有理数取余(费马小定理)
题目描述 给出一个有理数 c=a/b ,求 c mod 19260817的值. 说明 对于所有数据, 0≤a,b≤10^10001 分析: 一看题 这么短 哇简单!况且19260817还是个素数!(美 ...
- 【BZOJ4458】GTY的OJ
题面 Description 身为IOI金牌的gtyzs有自己的一个OJ,名曰GOJ.GOJ上的题目可谓是高质量而又经典,他在他的OJ里面定义了一个树形的分类目录,且两个相同级别的目录是不会重叠的.比 ...
- Nginx的server为0.0.0.0/0.0.0.1的作用?
看到kong默认的代理和后台server 都是0.0.0.0,代理到上游的服务器proxy_pass $upstream_scheme://kong_upstream;配置如下, upstream k ...
- [置顶]
kubernetes将外部服务映射为内部服务
在实际应用中,一般不会把mysql这种重IO.有状态的应用直接放入k8s中,而是使用专用的服务器来独立部署.而像web这种无状态应用依然会运行在k8s当中,这时web服务器要连接k8s管理之外的数据库 ...
- Linux文件压缩与解压命令
1 .zip 格式压缩与解压 压缩命令 zip 压缩文件名 源文件 zip -r 压缩目录名 源目录 解压命令 unzip 文件名 td@td-Lenovo-IdeaPad-Y41 ...
- DevExpress控件之popupMenu
一.首次创建 1.可直接从工具栏拉一个PopupMenu出来, 2.右键Customize,Yes(提示是否自动创建BarManager,并为popupmenu绑定这个BarManager): 3.编 ...
- 从头认识Spring-1.7 如何通过属性注入Bean?(1)-如何通过属性向对象注入值?
这一章节我们来讨论一下如何通过属性注入Bean? 这一章节分为两部分,第一部分我们通过属性向对象注入值,第二部分我们通过属性向对象注入还有一个对象的引用. 1.如何通过属性向对象注入值? (1)dom ...
- 使用Fiddler作为简单的mockserver
转载: http://blog.csdn.net/xt0916020331/article/details/66544526 开发中经常遇到调试过程中对接系统接口无法联调或者后台未开发完成等情况.这 ...