1.任意裁剪平面

Opengl中,除了视景体的立方体裁剪平面之外,另外还可以额外指定多达6个裁剪平面,对视景体做进一步限制。每一个平面都由平面公式定义:Ax+By+Cz+D = 0.裁剪平面的指定通过函数:glClipPlane(GLenum plane,const GLdouble* equation)确定。plane可能值为:GL_CLIP_PLANE0--GL_CLIP_PLANE6。equation为大小为4的数组:顺序分别对应参数A,B,C,D.最后所有满足(A,B,C,D)*M(-1)*(Xe,Ye,Ze,We)(T) ≥0的点位于平面定义的半空间内。如下图所示:
示例代码如下:
#include <vgl.h>void init(void)
{glClearColor(0.0,0.0,1.0,0.0);glShadeModel(GL_FLAT);
}
void display()
{GLdouble eq0 [4] = {0.0,1.0,0.0,0.0};GLdouble eq1 [4] = {1.0,0.0,0.0,0.0};glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0,0.0,0.0);glPushMatrix();  //把当前矩阵压入第二层,顶层也是当前矩阵glTranslatef(0.0,0.0,0.0); //针对顶层矩阵进行变换glClipPlane(GL_CLIP_PLANE0,eq0);glEnable(GL_CLIP_PLANE0);   //使当前平面裁剪有效glClipPlane(GL_CLIP_PLANE1,eq1);glEnable(GL_CLIP_PLANE1);glRotatef(90,1,0,0);glutWireSphere(1.0,40,40);glPopMatrix();  //当前矩阵被丢弃,第二层矩阵提前,恢复现场glFlush();
}
void  reshape(int w, int h)
{glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity(); //加载单位阵到栈顶//gluPerspective(60,(GLsizei)w/(GLsizei)h,1,20);glFrustum(-10,10,-10,10,0,-100);glMatrixMode(GL_MODELVIEW); //恢复到模型视图 }
int main(int argc, char** argv)
{glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(400,400);glutInitWindowPosition(200,200);glutCreateWindow(argv[0]);  //指向的是*.exe文件init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutMainLoop();return 0;
}

输出裁剪前后结果:

         

2.程序细节的剖析

2.1 glutWireSphere

glutWireSphere是GLUT工具包中的一个函数。该函数用于渲染一个球体(由线条构成球体)。球体球心位于原点。在OpenGL中默认的原点就是窗口客户区的中心。
函数原型:void glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
参数介绍:
  • radius  球体的半径
  • slices  以Z轴上线段为直径分布的圆周线的条数(将Z轴看成地球的地轴,类似于经线)
  • stacks  围绕在Z轴周围的线的条数(类似于地球上纬线)
相对于半径,后两个参数赋予较大的值, 渲染出来的球体表面看不出来线条。此时众多线条已经构成比较紧密的球面。相关函数:glutSolidSphere。

2.2 OpenGL中glFrustum()和gluPerspective()的相互转换

OpenGL中在窗口的大小发生变化的时候会触发reshape()函数,这里会传入一个新的宽和高,在reshape()函数中我们会设置投影矩阵,在可以使用OpenGL基础函数glFrustum()函数和glu函数gluPerspective()函数。
OpenGL函数glFrustum是建立一个平截头体的函数,在建立投影矩阵的时候使用。glu的gluPerspective()函数是对OpenGL基础函数glFrustum()的封装。两者提供的参数也不一致.
下面分析gluPerspective()函数是如何对glFrustum()函数进行封装的。
两个函数的声明:
glFrustum(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble zNear,GLdouble zFar);
gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar);
要理解两者间的联系,还得研究它们的原理。下面是两个函数的原理图:
      
理解了这些关系之后就可以列出两者之间的转换关系了。

void MyPerspective( GLdouble fov, GLdouble aspectRatio, GLdouble zNear, GLdouble zFar )
{// 使用glu库函数,需要添加glu.h头文件//gluPerspective( fov, aspectRatio, zNear, zFar );// 使用OpenGL函数,但是需要添加math.h头文件GLdouble rFov = fov * 3.14159265 / 180.0;glFrustum( -zNear * tan( rFov / 2.0 ) * aspectRatio,zNear * tan( rFov / 2.0 ) * aspectRatio,-zNear * tan( rFov / 2.0 ),zNear * tan( rFov / 2.0 ),zNear, zFar );
}

2.3 glPushMatrix和glPopMatrix矩阵栈顶操作

OpenGL中图形绘制后,往往需要一系列的变换来达到用户的目的,而这种变换实现的原理是又通过矩阵进行操作的。opengl中的变换一般包括视图变换、模型变换、投影变换等,在每次变换后,opengl将会呈现一种新的状态(这也就是我们为什么会成其为状态机)。
有时候在经过一些变换后我们想回到原来的状态,就像我们谈恋爱一样,换来换去还是感觉初恋好,怎么办?强大的opengl就帮我们提供了两个函数:giPushMatrix()和glPopMatrix();

首先我们要知道,对于矩阵的操作都是对于矩阵栈的栈顶来操作的。当前矩阵即为矩阵栈的栈顶元素,而对当前矩阵进行平移、旋转等的变换操作也同样是对栈顶矩阵的修改。所以我们在变换之前调用giPushMatrix()的话,就会把当前状态压入第二层,不过此时栈顶的矩阵也与第二层的相同。
当经过一系列变换后,栈顶矩阵被修改,此时调用glPopMatrix()时,栈顶矩阵被弹出,又会恢复为原来的状态。
函数的作用过程可以用下图描述,更为直观。

OpenGL编程指南9:裁剪平面+glPushMatrix和glPopMatrix矩阵栈顶操作相关推荐

  1. OpenGL的glPushMatrix和glPopMatrix矩阵栈顶操作函数详解

    OpenGL中图形绘制后,往往需要一系列的变换来达到用户的目的,而这种变换实现的原理是又通过矩阵进行操作的.opengl中的变换一般包括视图变换.模型变换.投影变换等,在每次变换后,opengl将会呈 ...

  2. OpenGL的glPushMatrix和glPopMatrix矩阵栈顶操作函数

    在之前的博客中,我就说过后面会详细讲解这两个函数.今天让我们来认识下它们(glPushMatrix和glPopMatrix函数). OpenGL中图形绘制后,往往需要一系列的变换来达到用户的目的,而这 ...

  3. opengl-函数讲解 glPushMatrix和glPopMatrix矩阵栈顶操作【转载自追寻1024的程序猿 】

    阅读目录 OpenGL中图形绘制后,往往需要一系列的变换来达到用户的目的,而这种变换实现的原理是又通过矩阵进行操作的.opengl中的变换一般包括视图变换.模型变换.投影变换等,在每次变换后,open ...

  4. OpenGL编程指南7:视图-

    1.前言 计算机图形学的要点就是创建三维物体的二维图像(图像必须是二维的,因为他是在平面的屏幕上显示的).但是,当我们决定怎样在屏幕上绘图时,必须使用三维坐标的方式考虑. 为了把一个物体的三维坐标变成 ...

  5. OpenGL编程指南4:双缓冲实现运行

    1.前言 绘制一个旋转的方块,主要为了说明glutSwapBuffers()函数的用法. 同时也为了学习如何使用GLUT控制输入设备,并打开或关闭空闲处理函数. 2.OpenGL编程及程序剖析 /** ...

  6. 《OpenGL编程指南》一第2章 着色器基础

    本节书摘来自华章出版社<OpenGL编程指南>一书中的第2章,作者 Bill Licea-Kane ,更多章节内容可以访问云栖社区"华章计算机"公众号查看 第2章 着色 ...

  7. OpenGL编程指南5:学习绘制不同风格的曲线

    1.不同风格曲线绘制 #include <vgl.h> //宏定义;当定义的宏不能用一行表达完整时,可以用"\"表示下一行继续 #define drawOneLine( ...

  8. OpenGL编程指南3:GLUT:OpenGL使用工具库

    1.前言 我们知道的,OpenGL包含了很多的渲染函数,这些函数的设计目的就是独立与任何窗口系统或操作系统.因此,他并没有包含打开窗口或者从键盘或鼠标读取事件的函数.遗憾的是,如果连最基本的打开窗口的 ...

  9. opengl编程指南第8版源码编译详细说明

    1. 到:https://github.com/openglredbook/examples 下载完全版的源码examples-master.zip,大小有131MB左右,不要下载缩略版的,否则\bi ...

最新文章

  1. 操作篇 ARP协议欺诈
  2. Netty入门(一)环境搭建及使用
  3. java8与函数编程资料
  4. 商标申请的企业法律服务可避免法律风险
  5. java servlet 配置_servlet与javabean配置
  6. (转)Bootstrap 之 Metronic 模板的学习之路 - (3)源码分析之 body 部分
  7. php开发中常用函数总结,PHP开发中常用函数总结
  8. 摘录本的摘录内容_使用tSQLtSQL单元测试数据仓库摘录
  9. python类修饰器_Python 中使用类修饰器修饰类方法如何处理 self?
  10. POJ1860Currency Exchange(SPFA)
  11. Uva 12063 Zero and Ones
  12. java判断对象无数据_Java 判断实体对象及所有属性是否为空的操作
  13. jsonrpc(jsonrpc4j)demo
  14. 德歌:阿里云RDS PG最佳实践
  15. android 清理系统垃圾,安卓手机怎么清理系统垃圾
  16. Modern C++ JSON nlohmann::json 使用详解
  17. 字节序: big-endian vs little-endian
  18. firefox autoproxy 实现ssh代理上网,针对XP,新版可以用firefox的foxproxy组件
  19. c语言机票座位预定系统_c语言编写~~~机票座位预订系统
  20. 注意力机制(attention)学习记录(二)

热门文章

  1. php歌唱比赛评分表格,歌唱比赛评分表格.pdf
  2. 1564 把箱子放进仓库里 I
  3. 微信小程序 -- 自定义底部弹出框(带动画--滑入滑出)
  4. 实验一 基本 UI 界面设计
  5. dotnet 删除文件夹方法
  6. 新游记-走在新加坡河畔
  7. Android应用程序获取ROOT权限的方法
  8. 春分, the Spring Equinox, the Vernal Equinox
  9. 批量图片转换成矩阵matlab
  10. phpspider 完整使用技巧 含代码