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

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

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

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

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

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

  1. int main(int argc, char **argv) {
  2.  
  3. // init GLUT and create window
  4. glutInit(&argc, argv);
  5. glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
  6. glutInitWindowPosition(,);
  7. glutInitWindowSize(,);
  8. glutCreateWindow("Lighthouse3D- GLUT Tutorial");
  9.  
  10. // register callbacks
  11. glutDisplayFunc(renderScene);
  12.  
  13. // Here is our new entry in the main function
  14. glutReshapeFunc(changeSize);
  15.  
  16. // enter GLUT event processing cycle
  17. glutMainLoop();
  18.  
  19. return ;
  20. }

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

  1. void changeSize(int w, int h) {
  2.  
  3. // Prevent a divide by zero, when window is too short
  4. // (you cant make a window of zero width).
  5. if(h == )
  6. h = ;
  7. float ratio = 1.0* w / h;
  8.  
  9. // Use the Projection Matrix
  10. glMatrixMode(GL_PROJECTION);
  11.  
  12. // Reset Matrix
  13. glLoadIdentity();
  14.  
  15. // Set the viewport to be the entire window
  16. glViewport(, , w, h);
  17.  
  18. // Set the correct perspective.
  19. gluPerspective(,ratio,,);
  20.  
  21. // Get Back to the Modelview
  22. glMatrixMode(GL_MODELVIEW);
  23. }

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

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

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

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

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

完整代码如下:

  1. #ifdef __APPLE__
  2. #include <GLUT/glut.h>
  3. #else
  4. #include <GL/glut.h>
  5. #endif
  6.  
  7. void changeSize(int w, int h) {
  8.  
  9. // Prevent a divide by zero, when window is too short
  10. // (you cant make a window of zero width).
  11. if (h == )
  12. h = ;
  13.  
  14. float ratio = w * 1.0 / h;
  15.  
  16. // Use the Projection Matrix
  17. glMatrixMode(GL_PROJECTION);
  18.  
  19. // Reset Matrix
  20. glLoadIdentity();
  21.  
  22. // Set the viewport to be the entire window
  23. glViewport(, , w, h);
  24.  
  25. // Set the correct perspective.
  26. gluPerspective(,ratio,,);
  27.  
  28. // Get Back to the Modelview
  29. glMatrixMode(GL_MODELVIEW);
  30. }
  31.  
  32. void renderScene(void) {
  33.  
  34. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  35.  
  36. glBegin(GL_TRIANGLES);
  37. glVertex3f(-,-,-5.0);
  38. glVertex3f(,0.0,-5.0);
  39. glVertex3f(0.0,,-5.0);
  40. glEnd();
  41.  
  42. glutSwapBuffers();
  43. }
  44.  
  45. int main(int argc, char **argv) {
  46.  
  47. // init GLUT and create window
  48. glutInit(&argc, argv);
  49. glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
  50. glutInitWindowPosition(,);
  51. glutInitWindowSize(,);
  52. glutCreateWindow("Lighthouse3D - GLUT Tutorial");
  53.  
  54. // register callbacks
  55. glutDisplayFunc(renderScene);
  56. glutReshapeFunc(changeSize);
  57.  
  58. // enter GLUT event processing loop
  59. glutMainLoop();
  60.  
  61. return ;
  62. }

[译]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. luogu P3819 松江1843路

    题目描述 涞坊路是一条长L米的道路,道路上的坐标范围从0到L,路上有N座房子,第i座房子建在坐标为x[i]的地方,其中住了r[i]人. 松江1843路公交车要在这条路上建一个公交站,市政府希望让最多的 ...

  2. 【BZOJ4458】GTY的OJ

    题面 Description 身为IOI金牌的gtyzs有自己的一个OJ,名曰GOJ.GOJ上的题目可谓是高质量而又经典,他在他的OJ里面定义了一个树形的分类目录,且两个相同级别的目录是不会重叠的.比 ...

  3. JDBC_PreparedStatement 防sql注入

    package songyan.jdbc.login.prepared; import java.sql.Connection; import java.sql.DriverManager; impo ...

  4. intel 硬盘加速技术

    Intel Smart Response Technology 混合硬盘技术 Intel Rapid Storage Technology SERVER:

  5. 【SQL】在SQL Server中多表关联查询问题

    好久没有写SQL语句的多表连接查询,总在用框架进行持久化操作.今天写了一个多表关联查询,想根据两个字段唯一确定一条数据 失败的案例如下: SELECT cyb.id,ad.name FROM [Gen ...

  6. 跟我一起透彻理解template模板模式

    #include <iostream> using namespace std; //template模式. class Base { public: void DealWhat() { ...

  7. 初识Nginx及编译安装Nginx

    初识Nginx及编译安装Nginx 环境说明: 系统版本    CentOS 6.9 x86_64 软件版本    nginx-1.12.2 1.什么是Nginx? 如果你听说或使用过Apache软件 ...

  8. 联想T470设置U盘启动

    联想T470设置U盘启动 学习了:http://www.udaxia.com/upqd/10092.html # F12 in Enter in USB HDD 如果不行: App Menu > ...

  9. ubuntu+tomcat,多环境、自动化部署脚本,git+maven+tomcat+ubuntu

     1.切换到/opt/code目录,没有利用mkdir code创建code目录,新建deploy.sh 脚本文件,内容如下 projectName=""; #默认tomcat目录 ...

  10. vi 替换操作

    举例一: ,$s/// 从第一行到最后一行 147都替换为150 举例二: 例:替换当前文件中所有old为new :%s/old/new/g #%表示替换说有行,g表示替换一行中所有匹配点. 举例三: ...