3/4、事例三、四 :透视投影(Perspective)、正射投影(Ortho)

自作多情 提交于 2019-11-27 10:06:26
namespace sharpGLTest03
{
        // 主表单类
    public partial class SharpGLForm : Form
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="SharpGLForm"/> class.
        /// </summary>
        public SharpGLForm()
        {
            InitializeComponent();
        }

        //  处理OpenGL控件的OpenGLDraw事件
        //  "sender":事件的来源
        //  "e":包含事件数据的实例
        private void openGLControl_OpenGLDraw(object sender, RenderEventArgs e)
        {
            //  获取OpenGL对象
            OpenGL gl = openGLControl.OpenGL;

            //  清除颜色和深度缓冲区
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

            //  加载单位矩阵
            gl.LoadIdentity();

            //  围绕Y轴旋转
            //gl.Rotate(rotation, 0.0f, 1.0f, 0.0f);

            //  画一个彩色的金字塔
            gl.Begin(OpenGL.GL_TRIANGLES);

            {
                //  画三角形
                gl.Vertex(0.0f, 0f, 0.0f);
                gl.Vertex(-1.0f, -1f, 0.0f);
                gl.Vertex(1.0f, -1f, 0.0f);
            }

            //gl.Color(1.0f, 0.0f, 0.0f);
            //gl.Vertex(0.0f, 1.0f, 0.0f);
            //gl.Color(0.0f, 1.0f, 0.0f);
            //gl.Vertex(-1.0f, -1.0f, 1.0f);
            //gl.Color(0.0f, 0.0f, 1.0f);
            //gl.Vertex(1.0f, -1.0f, 1.0f);
            //gl.Color(1.0f, 0.0f, 0.0f);
            //gl.Vertex(0.0f, 1.0f, 0.0f);
            //gl.Color(0.0f, 0.0f, 1.0f);
            //gl.Vertex(1.0f, -1.0f, 1.0f);
            //gl.Color(0.0f, 1.0f, 0.0f);
            //gl.Vertex(1.0f, -1.0f, -1.0f);
            //gl.Color(1.0f, 0.0f, 0.0f);
            //gl.Vertex(0.0f, 1.0f, 0.0f);
            //gl.Color(0.0f, 1.0f, 0.0f);
            //gl.Vertex(1.0f, -1.0f, -1.0f);
            //gl.Color(0.0f, 0.0f, 1.0f);
            //gl.Vertex(-1.0f, -1.0f, -1.0f);
            //gl.Color(1.0f, 0.0f, 0.0f);
            //gl.Vertex(0.0f, 1.0f, 0.0f);
            //gl.Color(0.0f, 0.0f, 1.0f);
            //gl.Vertex(-1.0f, -1.0f, -1.0f);
            //gl.Color(0.0f, 1.0f, 0.0f);
            //gl.Vertex(-1.0f, -1.0f, 1.0f);
            gl.End();

            //  轻推旋转
            //rotation += 3.0f;
        }



        //  处理OpenGL控件的OpenGLInitialized事件
        private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
        {
            //  TODO: 在这里初始化OpenGL

            //  获取OpenGL对象
            OpenGL gl = openGLControl.OpenGL;

            //  设置清晰的颜色
            gl.ClearColor(0, 0, 0, 0);
        }


        //  处理OpenGL控件的Resized事件
        private void openGLControl_Resized(object sender, EventArgs e)
        {
            // 在此设置投影矩阵

            //  获取OpenGL对象
            OpenGL gl = openGLControl.OpenGL;

            //  设置投影矩阵;设置当前矩阵模式,对投影矩阵应用随后的矩阵操作
            gl.MatrixMode(OpenGL.GL_PROJECTION);

            //  加载身份;重置当前指定的矩阵为单位矩阵,将当前的用户坐标系的原点移到了屏幕中心
            gl.LoadIdentity();

            //  创建透视投影变换
            /*
             * 创建透视效果的函数名和原型
             * Perspective(double fovy, double aspect, double zNerar, double zFar)
             * fovy:是控制视野子在XY平面的角度,范围是0——180度。视野度数
             * aspect:是窗口的纵横比
             * zNerar,zFar:分别是近处和远处的裁面位置
             * 
             * */
            //gl.Perspective(60.0f, (double)Width / (double)Height, 0.01, 100.0);

            //创建正射投影变换
            /*
             * Ortho(double left, double right, double bottom, double top,double near,double far)
             * near:近平面距离;far:远平面距离
             * near、far 可以认为是Z轴方向上的近裁剪平面和远裁剪平面
             * 正射投影的最大特点:无论物体距离相机有多远,投影后的物体大小尺寸不变
             * */
            /*
             * 正射投影之后,三角形就被置于这个矩阵长方体(-2,2,-3,3,-2,-5)的视景中了,以后LookAt就是在看这个视影体中的内容,
             * 如果摄像机的视点设置有超出这个视景体的部分将看不到,相当于被裁剪了
             * */
            gl.Ortho(-2,2,-3,3,-2,-5);

            //  视点变换
            /* 
             * 视点变换的函数LookAt的原形为:
             * LookAt(double eyex.double eyey,double eyez,double centerx,double centery,double centerz,double upx,double upy,double upz);
             * 这个函数是做视点变换用的,你可以认为它是设置摄像机的函数
             * 在OpenGL中,默认时视点定位于坐标系的原点,初始方向指向Z轴负方向,前面说过,默认的三维模型也是贴着世界坐标系的Z轴0的深度上
             * 放置的,因此,如果不进行视点变换,则摄像机正好贴着物体,什么也看不见。这就是为什么在上一节的代码里面要有一句代码gl.Transkate()
             * 用于把物体往Z轴负方向移动一定距离的原因
             * eyex,eyey, eyez ; 表示摄像机本身位于世界坐标系中的位置
             * centerx,centery,centerz ;相当于调整了摄像机目标点的位置
             *  upx,upy,upz ;相当于在旋转3dmax目标摄像机;这个参数的值并不是角度值,而是向量,数值的大小没意义,
             * 正负值才有意义。upx,upy只能在上下,左右,45度这几个角度中变换,而且upz取值似乎没什么意义 ;
             * */
            // 透视投影——从后左方看画出的三维三角形
            //gl.LookAt(-5, 5, -5, 0, 0, 0, 0, 1, 0);

            // 透视投影——从正前方看画出的三维三角形
            gl.LookAt(0, 0, 1, 0, 0, -10, 0, 1, 0);

            // 正射投影——gl.Ortho(-2,2,-3,3,-2,-5);LookAt第三个参数eyez要位于Ortho参数near、far(即-2,-5)之间的原因
            gl.LookAt(0, 0, -3, 0, 0, -10, 0, 1, 0);

            //  设置当前矩阵为模型视图矩阵
            gl.MatrixMode(OpenGL.GL_MODELVIEW);
        }

        //  当前的轮换
        //private float rotation = 0.0f;
    }
}

 

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