[译]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可以让应用程序自动监测键盘输入,包括普通按键和 ...
随机推荐
- MySql笔记之修改MySQL提示符
首先,了解下MYSQL提示符是神马东东 就是每次登陆mysql后出现的提示符 如果我们不喜欢这个提示符呢,那我们就改成我们喜欢的样子. 系统参数提示符 举个栗子 就改成相应的提示符了,那么可否随意改名 ...
- Count Primes -- LeetCodes (primality test)
Description: Count the number of prime numbers less than a non-negative number, n. 思路:这题第一种思路是写一个is_ ...
- java.util.List.subList ,开区间和闭区间
比如集合中的内容为1,2,3,4,5list.sublist(2,4)就返回一个子集合:它的内容包括从下标为2到下标为4,而且这是左闭右开的就是说是从大于等于2到小于4那子集内容就是3,4(集合的下标 ...
- ES6里的修饰器Decorator
修饰器(Decorator)是一个函数,用来修改类的行为. 一.概述 ES6 引入了这项功能,目前 Babel 转码器已经支持Decorator 首先,安装babel-core和babel-plugi ...
- StreamingContext、DStream、Receiver深度剖析
本课分成四部分讲解,第一部分对StreamingContext功能及源码剖析:第二部分对DStream功能及源码剖析:第三部分对Receiver功能及源码剖析:最后一部分将StreamingConte ...
- 速查笔记(Linux Shell编程<上>)
转载自: http://www.cnblogs.com/stephen-liu74/archive/2011/11/01/2202027.html 零.shell中的内部变量: 1. $?: ...
- tar命令解压缩出错
[root@zhoucentos share1]# tar zxvf otp_src_19..tar.gz gzip: stdin: not in gzip format tar: Child ret ...
- es创建索引的格式,并初始化数据
es创建索引的格式,并初始化数据 学习了:https://www.imooc.com/video/15759 1, 创建格式 POST 127.0.0.1:9200/book/novel/_mappi ...
- [Functional Programming] Define Discrete State Transitions using the State ADT
We build our first state transactions as two discrete transactions, each working on a specific porti ...
- 性能测试之Tomcat优化
1.Tomcat最大连接数等配置 Tomcat的server.xml中Context元素的以下参数都是什么意思? <Connector port="8080"maxThr ...