6、事例六:裁剪变换(ClipPlane)

狂风中的少年 提交于 2019-11-27 10:07:05
namespace sharpGLTest06
{
    public partial class SharpGLForm : Form
    {
        public SharpGLForm()
        {
            InitializeComponent();
        }

        private void openGLControl_OpenGLDraw(object sender, RenderEventArgs e)
        {

            OpenGL gl = openGLControl.OpenGL;
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
            gl.LoadIdentity();

            double[] eqn = new double[4] { 1f, 0f, 1f, 0f };

            //白色
            gl.Color(1.0, 1.0, 1.0);

            //建立模型堆栈,将当前位置保存起来(入栈)
            /* 详解
             * 当你做一些移动或旋转等变换后,使用glPushMatrix(),OpenGL会把这个变换后的位置和角度保存起来;
             * 然后你再随便坐第二次移动或旋转变换,再用glPopMatrix(),OpenGL就会把刚刚保存的那个位置和角度恢复;
             * 消除上一次变换对本次变换的影响
             * */
            gl.PushMatrix();
            {
                gl.Translate(2, -2, -3);
                gl.Rotate(-90.0, 1.0, 0.0, 0.0);
                drawSphere(gl);
            }
            // 将保存的位置放出(出栈)
            gl.PopMatrix();

            gl.PushMatrix();
            {
                // 定义一个裁剪平面
                /*
                 * ClipPlane(OpenGL.GL_CLIP_PLANE0, 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)表示裁剪掉后半平面
                 * */
                gl.ClipPlane(OpenGL.GL_CLIP_PLANE0, eqn);
                gl.Enable(OpenGL.GL_CLIP_PLANE0);
                drawGrid(gl);
            }
            gl.PopMatrix();

            gl.Flush();

        }
        //曲面绘制
        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, 20, 10);
            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 = -50; i <= 50; i += 1)
            {
                //绘制线
                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();
        }


        private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
        {
            OpenGL gl = openGLControl.OpenGL;
            gl.ClearColor(0, 0, 0, 0);
        }

        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, 0.01, 100.0);
            gl.LookAt(0, 5, 10, 0, 0, 0, 0, 1, 0);
            gl.MatrixMode(OpenGL.GL_MODELVIEW);
        }
    }
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!