OpenGL学习09_裁剪平面ClipPlane

除了视景体的6个裁剪平面(左、右、底、顶、近和远)之外,还可以另外再指定最多可达6个的其他裁剪平面,对视景体施加进一步的限制。

每个平面都是由它的方程式Ax + By + Cz + D= 0的系数所指定的。裁剪平面会根据模型和视图矩阵自动执行适当的变换。最终的裁剪区域将是视景体与其他裁剪平面定义的所有半空间的交集。记住,OpenGL会自动对部分被裁剪的多边形的边进行正确的重构。

void glClipPlane(GLenum plane, const GLdouble *equation); 

定义一个裁剪平面。equation参数指向平面方程Ax + By + Cz + D = 0的4个系数。满足(A B C D)M-1 (xe ye ze we) T≥0的所有视觉坐标(xe ye ze we)点都位于这个平面定义的半空间中,其中M是在调用glClipPlane()时的当前模型视图矩阵。所有不是位于这个半空间内的点都将裁剪掉。plane参数是GL_CLIP_PLANEi,其中i是一个整数,表示需要定义哪个有效裁剪平面。i的值位于0和最大其他裁剪平面数减1之间。

我们需要启用每个被定义的裁剪平面:

glEnable(GL_CLIP_PLANEi); 

也可以用下面这个函数禁用一个裁剪平面:

glDisable(GL_CLIP_PLANEi); 

所有的OpenGL实现都必须支持至少6个其他裁剪平面,有些实现可能允许超过6个的其他裁剪平面。可以用GL_MAX_CLIP_PLANES为参数调用glGetIntegerv()函数,查询自己使用的OpenGL实现所支持的其他裁剪平面的最大数量。

调用glClipPlane()函数所执行的裁剪是在视觉坐标中完成的,而不是在裁剪坐标中进行的。如果投影矩阵为奇异矩阵(也就是把三维坐标压平到二维坐标的真正投影矩阵),这个区别就非常大。在视觉坐标中进行裁剪时,即使投影矩阵是奇异矩阵,裁剪仍然是在三维空间中进行的。

下面的例子通过两个裁剪平面对球体进行了裁剪。

//
//  main.cpp
//  OpenGL_10_ClipPlane
//
//  Created by apple on 15/1/19.
//  Copyright (c) 2015年 cc. All rights reserved.
//

#include <iostream>

#include <GLUT/GLUT.h>

/**
 *  初始化操作
 */
void init() {
    //设置清屏色
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    //设置着色模式,填充色与顶点一致
    glShadeModel(GL_FLAT);
}

/**
 *  展示绘制效果
 */
void display() {

    //清理颜色缓冲区
    glClear(GL_COLOR_BUFFER_BIT);
    //设置绘制颜色
    glColor3f(1.0, 1.0, 1.0);
    //复制当前矩阵并保存到栈顶
    glPushMatrix();
    //沿z轴负方向移动5个单位长度
    glTranslatef(0.0f, 0.0f, -5.0f);

    //定义裁剪平面数组, Ax + By + Cz + D = 0
    GLdouble equn[4] = {0.0f, 1.0f, 0.0f, 0.0f};
    GLdouble equn2[4] = {1.0f, 0.0f, 0.0f, 0.0f};

    //设置裁剪平面,y>0
    glClipPlane(GL_CLIP_PLANE0, equn);
    glEnable(GL_CLIP_PLANE0);

    //设置裁剪平面,x>0
    glClipPlane(GL_CLIP_PLANE1, equn2);
    glEnable(GL_CLIP_PLANE1);

    //沿x轴旋转90度
    glRotatef(90.0f, 1.0f, 0.0f, 0.0f);

    //渲染一个球体,球体半径,以Z轴上线段为直径分布的圆周线的条数(经线),围绕在Z轴周围的线的条数(维线)
    glutWireSphere(2.0f, 20.0f, 16.0f);

    //弹出栈顶矩阵
    glPopMatrix();

    //强制完成绘制指令
    glFlush ();
}

/**
 *  调整窗口尺寸
 *
 *  @param width  宽度
 *  @param height 高度
 */
void reshape(int width, int height) {
    //设置视口矩形区域,在默认情况下,视口被设置为占据打开窗口的整个像素矩形
    glViewport(0, 0, (GLsizei)width, (GLsizei)height);
    //之后的矩阵操作定义为投影矩阵操作
    glMatrixMode(GL_PROJECTION);
    //等于是将之前矩阵变换导致变化过的栈顶矩阵重新归位,置为单位矩阵!等于是之前的矩阵变换带来的影响到此为止了!
    glLoadIdentity();

    //创建一个表示对称透视视图平截头体的矩阵
    //设置眼睛睁开的角度,视景体的宽高比,近截面的距离,远截面的距离
    gluPerspective(60.0f, (GLfloat)width / (GLfloat)height, 1.0f, 20.0f);

    //之后的矩阵操作定义为模型视图矩阵操作
    glMatrixMode(GL_MODELVIEW);

}

int main(int argc, const char * argv[]) {

    //初始化GLUT库
    glutInit(&argc, (char**)argv);
    //设置单缓冲,RGB像素格式的窗口
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    //设置窗口大小
    glutInitWindowSize(500, 500);
    //设置窗口坐标
    glutInitWindowPosition (100, 100);
    //创建窗口
    glutCreateWindow("ClipPlane");

    //初始化操作
    init();

    //设置展示的回调方法
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);

    //绘制线程开始循环
    glutMainLoop();

    return 0;
}

本文由CC原创总结,如需转载请注明出处:http://blog.csdn.net/oktears/article/details/42915623

时间: 2024-10-09 20:31:19

OpenGL学习09_裁剪平面ClipPlane的相关文章

OpenGL之裁剪平面

在OpenGL中,除了视景体的6个裁剪面(左.右.顶.底.远和近)外,我们还可以指定最多6个裁剪面. 我们知道,一个平面,它是由Ax+By+Cz+D = 0这个三元一次函数构成.是怎么样一个平面,就由这个函数的系数决定. 那么,有这样一个函数: void glClipPlane(GLenum plane, const GLdouble* equation); 这个函数就是用来指定裁剪面的. plane这个参数,看到它的类型为枚举类型. 这个参数可以为6种,为GL_PLANEi(0 < i <

OpenGL学习进程(5)第三课:视口与裁剪区域

本节是OpenGL学习的第三个课时,下面介绍如何运用显示窗体的视口和裁剪区域:     (1)知识点引入:     1)问题现象: 当在窗体中绘制图形后,拉伸窗体图形形状会发生变化: #include <GL/glut.h> #include <math.h> const float Pi = 3.1415926f; const int n = 1000; const float R = 0.8f; void init(void) { glClearColor(0.0,0.0,0.

OpenGl学习进程(7)第五课:点、边和图形(二)边

本节是OpenGL学习的第五个课时,下面介绍OpenGL边的相关知识: (1)边的概念: 数学上的直线没有宽度,但OpenGL的直线则是有宽度的.同时,OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的.可以认为,OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定.     (2)如何绘制边: 1)OpenGL支持绘制三种类型的边: GL_LINES :指定两个顶点,在它们之间绘制一条直线.如果为GL_LINES指定了奇数个顶点,那么最后一个顶点会被忽略. GL

OpenGL学习进程(11)第八课:颜色绘制的详解

    本节是OpenGL学习的第八个课时,下面将详细介绍OpenGL的颜色模式,颜色混合以及抗锯齿.     (1)颜色模式: OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式. RGBA模式与索引模式的区别: 计算机必须为每个像素保存一些数据,在RGBA模式中数据就代表了颜色:而颜色索引模式中数据代表了一个索引,要获取真正的颜色值还需要查索引表.数据的数量是由帧缓存中的位面决定的.一个位面为一个像素的一个位的数据.假如是8位面的颜色,每个像素就有8个颜色位,因此就有2的8次方

OpenGL学习进程(4)第二课:绘制图形

本节是OpenGL学习的第二个课时,下面介绍如何用点和线来绘制图形:     (1)用点的坐标来绘制矩形: #include <GL/glut.h> void display(void) { // clear all pixels glClear(GL_COLOR_BUFFER_BIT); // draw yellow polygon (rectangle) with corners at glColor3f(1.0, 1.0, 0.0); glBegin(GL_POLYGON); //绘制开

OpenGL学习进程(6)第四课:点、边和图形(一)点

本节是OpenGL学习的第四个课时,下面介绍OpenGL点的相关知识:     (1)点的概念:     数学上的点,只有位置,没有大小.但在计算机中,无论计算精度如何提高,始终不能表示一个无穷小的点.一般情况下,OpenGL中的点将被画成单个的像素,虽然它可能足够小,但并不会是无穷小.同一像素上,OpenGL可以绘制许多坐标只有稍微不同的点,但该像素的具体颜色将取决于OpenGL的实现. 点是OpenGL中绘制一切的基础.     (2)如何绘制点: 1)OpenGL为点的绘制提供了一系列函数

OpenGL学习进程(10)第七课:四边形绘制与动画基础

    本节是OpenGL学习的第七个课时,下面以四边形为例介绍绘制OpenGL动画的相关知识:     (1)绘制几种不同的四边形: 1)四边形(GL_QUADS) OpenGL的GL_QUADS图元用于绘制四边形,它根据每四个顶点绘制一个四边形. 注意:在使用四边形时必需记住四边形的四个角必须位于同一个平面中(不存在弯曲的四边形). 2)四边形带(GL_QUAD_STRIP) 该图元指定一个连接的四边形带.它们都保持相同方向的环绕. 3)通用多边形GL_POLYGON 我们可以用它绘制任意数

OpenGL学习笔记:拾取与选择

转自:OpenGL学习笔记:拾取与选择 在开发OpenGL程序时,一个重要的问题就是互动,假设一个场景里面有很多元素,当用鼠标点击不同元素时,期待作出不同的反应,那么在OpenGL里面,是怎么知道我当前鼠标的位置是哪一个物体呢? OpenGL有一套机制,叫做Picking, 里面涉及到几个核心概念: 1. selection mode. 选择模式 2. name stack. 名字栈 3. hit record. 命中记录 4. viewing volume. 视角范围 在OpenGL的pick

OpenGL学习日记-2014.12.21--光照

o(╯□╰)o深患中度拖延症,也是从开始写这篇笔记到结束居然用了一个月...虽然中间是发生了不少事,不过明明就有无数机会可以完成,就是拖着没写代码,各种借口...面对如此拖延症该如何是好QAQ 正文: 突然觉得这些日记写着写着就没什么意思...只是简单梳理一下书中的内容,没经过很多的思考,可不写心里更虚,怕自己几天就把看的书忘了.对于很多概念,都由于没有好好去写代码验证,而理解流于表面.对于光照这章也是下决心细细琢磨一番(现在才下的决心o(╯□╰)o),毕竟这很重要. 一.光照和颜色密切相关,光