OpenGL之裁剪平面

在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号裁剪,两者均启用的裁剪):

OpenGL之裁剪平面_第1张图片

OpenGL之裁剪平面_第2张图片

OpenGL之裁剪平面_第3张图片

OpenGL之裁剪平面_第4张图片


To be continued~


你可能感兴趣的:(OpenGL)