在OpenGL中,除了视景体定义的6个裁剪平面(上下左右前后)外, 用户还可以定义一个或者多个附加的裁剪平面,以去掉场景中无关的目标.

附加平面裁剪函数原型如下:

ClipPlane(OpenGL.GL_CLIP_PLANEi, double[] equation);

equation是一个拥有4个系数的数组, 它定义一个裁剪平面。equation参数指向平面方程Ax + By + Cz + D = 0的4个系数。

equation=(0,-1,0,0),前三个参数(0,-1,0)可以理解为法线向下,只有向下的,即Y<0的才能显示,最后一个参数0表示从z=0平面开始。这样就是裁剪掉上半平面。

相应的equation=(0,1,0,0)表示裁剪掉下半平面,

equation=(1,0,0,0)表示裁剪掉左半平面,

equation=(-1,0,0,0)表示裁剪掉右半平面,

equation=(0,0,-1,0)表示裁剪掉前半平面,

equation=(0,0,1,0)表示裁剪掉后半平面

上几节,讨论过透视投影和正射投影, 它们构成两种视景体, 本身包含了裁剪功能, 这个附加的裁剪功能如下图所示:

示意图可能有些不太直观, 笔者先引用3dsmax的裁剪效果, 让大家对所谓的裁剪的效果有个主观印象.

在3dsmax中, 摄像机有一个剪切平面的选项, 勾选后可以设定近距剪切的位置(左视图那条倾斜的红色线条就是近距剪切线的位置,它的位置是85.493), 设置一个值后, 看到如下图所示的裁剪的效果.

如果你移动摄像机的位置, 那么剪切的位置会随之改变.

在OpenGL中, 经笔者测试, 发现视点变换并不会影响裁剪结果, 反而是模型的几何变换(移动,旋转,缩放) 影响裁剪结果.

我们以代码来说明这个ClipPlane()函数的用法, 先上代码:

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharpGL; namespace clipPlane
{ public partial class SharpGLForm : Form
{ public SharpGLForm()
{
InitializeComponent();
} private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
gl.LoadIdentity(); double[] eqn = new double[] { 1f, 0f, 0f, 0f }; gl.Color(1.0, 1.0, 1.0); gl.PushMatrix();
{
gl.Translate(-, -, -);
gl.Rotate(-90.0, 1.0, 0.0, 0.0);
drawSphere(gl);
}
gl.PopMatrix(); gl.PushMatrix();
{
//gl.ClipPlane(OpenGL.GL_CLIP_PLANE0, eqn);
//gl.Enable(OpenGL.GL_CLIP_PLANE0);
drawGrid(gl);
}
gl.PopMatrix(); gl.Flush();
} private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
gl.ClearColor(, , , );
} private void openGLControl_Resized(object sender, EventArgs e)
{ OpenGL gl = openGLControl.OpenGL;
gl.MatrixMode(OpenGL.GL_PROJECTION);
gl.LoadIdentity();
gl.Perspective(60.0f, (double)Width / (double)Height,, 100.0);
gl.LookAt(, , , , , , , , );
gl.MatrixMode(OpenGL.GL_MODELVIEW);
} void drawSphere(OpenGL gl)
{
//画二次曲面球体绘制过程
gl.PushMatrix();
gl.Translate(2f, 1f, 2f); //绘制二次曲面
var sphere = gl.NewQuadric();
//设置二次却面绘制风格。gluQuadricDrawStyle。一般都是选用GLU_FILL风格,采用多边形来模拟
gl.QuadricDrawStyle(sphere, OpenGL.GLU_LINE);
//设置法线风格。gluQuadricNormals。一般都是使用GLU_SMOOTH风格,对每个顶点都计算法线向量,是默认方式
gl.QuadricNormals(sphere, OpenGL.GLU_SMOOTH);
//设置二次曲面的绘制方向。gluQuadricOrientation。一般使用GLU_OUTSIDE, 按照所有的法线都指向外面的方式绘制。是默认方式
gl.QuadricOrientation(sphere, (int)OpenGL.GLU_OUTSIDE);
//设置纹理。gluQuadricTexture。设置是否自动计算纹理。默认是GLU_FALSE。当需要使用纹理时应修改为GLU_TRUE.
gl.QuadricTexture(sphere, (int)OpenGL.GLU_FALSE); gl.Sphere(sphere, 3f, , );
gl.DeleteQuadric(sphere);
gl.PopMatrix();
} void drawGrid(OpenGL gl)
{
//绘制栅格线过程
gl.PushAttrib(OpenGL.GL_CURRENT_BIT); //保存当前属性
gl.PushMatrix(); //压入堆栈
gl.Translate(0f, 0f, 0f);
gl.Color(0f, 0f, 1f); //在X,Z平面上绘制网格
for (float i = -; i <= ; i += )
{
//绘制线
gl.Begin(OpenGL.GL_LINES);
//X轴方向
gl.Vertex(-50f, 0f, i);
gl.Vertex(50f, 0f, i);
//Z轴方向
gl.Vertex(i, 0f, -50f);
gl.Vertex(i, 0f, 50f);
gl.End();
}
gl.PopMatrix();
gl.PopAttrib();
} }
}

上面代码中,我把42,43行有关裁剪的代码注释了, 这时运行的效果如下图:

产生一个球体和一个栅格面, 我的裁剪会对这两个对象都发生作用, 这样便于观察效果.

启用第42,43行, 运行后, 裁剪发生作用, 效果是下面这样的:

左半平面被去掉了. 因为裁剪会对场景中所有对象发生作用, 因此栅格面也被连累了.

如果你想移动裁剪面的位置, 你需要对球体做几何变换. 改变下面这行代码的参数就可以了.

gl.Translate(-, -, -);

然而, 一般来说, 场景中的对象固定好位置之后, 是不能做几何变换的. 如果即不做几何变换, 又想裁剪该怎么办呢?

暂时我也不知道怎么办! 如果以后知道怎么办我会在这把这个知识点补全了. (如果你知道,谢谢回本贴教下我!)

下面是45度方向上的裁剪. 任意角度的裁剪貌视是不可以的.

本节源代码下载

原创文章,出自"博客园, 猪悟能'S博客" : http://www.cnblogs.com/hackpig/

SharpGL学习笔记(六) 裁剪变换的更多相关文章

  1. SharpGL学习笔记(五) 视口变换

    视口变换主是将视景体内投影的物体显示到二维的视口平面上. 在计算机图形学中,它的定义是将经过几何变换, 投影变换和裁剪变换后的物体显示于屏幕指定区域内. 前面我们讨论过的透视投影, 正射投影, 它们都 ...

  2. SharpGL学习笔记(七) OpenGL的变换总结

    笔者接触OpenGL最大的困难是: 经常调试一份代码时, 屏幕漆黑一片, 也不知道结果对不对,不知道如何是好! 这其实就是关于OpenGL"变换"的基础概念没有掌握好, 以至于对& ...

  3. SharpGL学习笔记(十一) 光源创建的综合例子:光源参数可调节的测试场景

    灯光的测试例子:光源参数可以调节的测试场景 先看一下测试场景和效果. 场景中可以切换视图, 以方便观察三维体和灯光的位置.环境光,漫射光,镜面反射光都可以在四种颜色间切换. 灯光位置和摄像机位置(Lo ...

  4. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  5. Learning ROS for Robotics Programming Second Edition学习笔记(六) indigo xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  6. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  7. ArcGIS案例学习笔记-批量裁剪地理模型

    ArcGIS案例学习笔记-批量裁剪地理模型 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 功能:空间数据的批量裁剪 优点:1.批量裁剪:任意多个目标数据,去裁剪任意 ...

  8. python3.4学习笔记(六) 常用快捷键使用技巧,持续更新

    python3.4学习笔记(六) 常用快捷键使用技巧,持续更新 安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使 ...

  9. Go语言学习笔记六: 循环语句

    Go语言学习笔记六: 循环语句 今天学了一个格式化代码的命令:gofmt -w chapter6.go for循环 for循环有3种形式: for init; condition; increment ...

随机推荐

  1. Linux入门基础教程之Linux下软件安装

    Linux入门基础教程之Linux下软件安装 一.在线安装: sudo apt-get install 即可安装 如果在安装完后无法用Tab键补全命令,可以执行: source ~/.zshrc AP ...

  2. Vue页面跳转$router.push 的用法

    vue2.0在使用的过程中, .vue文件之间的跳转,在template中的常见写法是: <router-link to="/miniCard/statement/horizon&qu ...

  3. OpenGL中各种坐标系的理解

    转载:https://blog.csdn.net/meegomeego/article/details/8686816 OPENGL坐标系可分为:世界坐标系和当前绘图坐标系. 世界坐标系以屏幕中心为原 ...

  4. 猫猫学iOS之小知识iOS启动动画_Launch Screen的运用

    猫猫分享,必须精品 原创文章.欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243? viewmode=contents 看下效果吧 比如新浪微博的 ...

  5. PHP上传原理及操作实现

    关于PHP上传文件的函数类库,网上有许多封装很完善,大家直接拿来用就可以. 本文章只是说下关于上传原理和简单的上传操作,老鸟就无视了哈^_^~ 还有一些安全性判断比如:服务端限制能接收图片类型的文件, ...

  6. npm安装包卡住不动的解决

    最近诸事不顺,今天更新/安装nodejs各种包也全都卡在各个环节,用ie设了全局代理貌似也没什么改观,于是到网上找找有没有国内镜像站,倒是发现了cnpmjs.org这个网站被推荐比较多,看他们主页,他 ...

  7. 点击除元素以外的任意地方隐藏元素js

    比如想实现点击列表弹出筛选器,点击其他任意地方关闭筛选器,如图 该筛选器class名 $(document).click(function () { $(".subMenu").h ...

  8. Spring Boot项目使用Eclipse进行断点调试Debug

    1.在命令行下定位到项目根目录,启动Spring Boot项目,命令如下: java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=80 ...

  9. C#特性文章学习

    http://www.cnblogs.com/rohelm/archive/2012/04/19/2456088.html http://www.cnblogs.com/liuxinxin/artic ...

  10. 【QT学习】QT GUI应用程序的框架,文件分析

    有几个名字,项目名,类名,界面对象名. 1.项目文件 项目名.pro(MyHelloQt.pro) 主要包括项目用到的模块,项目包含哪些源码文件,头文件,窗体文件,生成应用程序的名称. 由QT自动生成 ...