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


    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);
            }
        }
    }
  • 相关阅读:
    用两个栈实现队列(剑指09题)
    PHP 视频源文件加密方案
    PHP 实现大文件视频推流
    logstash笔记
    yum本地包的获取与安装
    IF.SVNAdmin安装 | SVN权限可视化管理
    Windows全局程序调用 Win + R
    Jenkins复制流水线命令行
    SVN hooks编写[Linux&Windows]
    AA压限, 语音识别去除语气词, 等
  • 原文地址:https://www.cnblogs.com/lotuses/p/11357966.html
Copyright © 2020-2023  润新知