在OpenGL中,除了视景体的6个裁剪面(左、右、顶、底、远和近)外,我们还可以指定最多6个裁剪面。
我们知道,一个平面,它是由Ax+By+Cz+D = 0这个三元一次函数构成。是怎么样一个平面,就由这个函数的系数决定。
那么,有这样一个函数:
void glClipPlane(GLenum plane, const GLdouble* equation);
这个函数就是用来指定裁剪面的。
plane这个参数,看到它的类型为枚举类型。
这个参数可以为6种,为GL_PLANEi(0 < i < 6)。
equation这个参数用来指定裁剪面的4个系数。
所以可以定义一个GLdouble类型的数组,长度为4。
启用当前裁剪面可以通过glEnable(GL_PLANEi)决定。
关闭当前裁剪面可以通过glDisable(GL_PLANEi)决定。
下面是一个裁剪平面的例子:
#include
int width = 300; //窗口大小
int height = 300;
GLfloat LightPosition[] = { 0.0f, 0.0f, 0.0f, 1.0f }; //光照
GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
void display(void)
{
GLdouble eqn[4] = { 0.0, 1.0, 0.0, 0.0 }; //裁剪系数
GLdouble eqn2[4] = { 1.0, 0.0, 0.0, 0.0 };
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除颜色和深度缓存
glLoadIdentity(); //重置当前的模型观察矩阵
glColor3f(0.5f, 0.5f, 0.5f); //设置颜色
glPushMatrix(); //将矩阵压入栈
glTranslatef(0.0f, 0.0f, -5.0f);
glClipPlane(GL_CLIP_PLANE0, eqn); //裁剪面
glEnable(GL_CLIP_PLANE0);
glClipPlane(GL_CLIP_PLANE1, eqn2);
glEnable(GL_CLIP_PLANE1);
glRotatef(90.0f, 1.0f, 0.0f, 0.0f); //饶x轴旋转90度
glutWireSphere(1.0, 20, 16); //绘制一个网格球体
glPopMatrix(); //将矩阵弹出栈
glFlush();
}
void init(void)
{
glMatrixMode(GL_PROJECTION); //投影矩阵
glLoadIdentity(); //重置投影矩阵
gluPerspective(60.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f); //透视投影
glMatrixMode(GL_MODELVIEW); //模型观察矩阵
glLoadIdentity(); //重置模型观察举证
glShadeModel(GL_SMOOTH); //平滑阴影
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //背景颜色
glClearDepth(1.0f); //设置深度缓存
glEnable(GL_DEPTH_TEST);//启用深度测试
glDepthFunc(GL_LESS); //深度类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //透视修正
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient); //设置光源
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
glEnable(GL_LIGHT0);
//glEnable(GL_LIGHTING);
}
void shaped(int w, int h) //窗口大小改变时调用
{
width = w;
height = h;
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
init();
gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv); //初始化GLUT
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); //初始化模式
glutInitWindowSize(300, 300); //初始化窗体大小
glutInitWindowPosition(300, 200); //初始化窗体位置
glutCreateWindow("裁剪平面"); //创建窗体
init(); //OpenGL的一些初始化
glutDisplayFunc(display); //注册display函数
glutReshapeFunc(shaped); //注册shaped函数
glutMainLoop(); //进入GLUT事件循环
return 0;
}
这个例子是裁剪一个网格球体。
效果图(分别为不启用裁剪,启用0号裁剪,启用1号裁剪,两者均启用的裁剪):
To be continued~