zoukankan      html  css  js  c++  java
  • 11、事例十一:光源创建综合例子;光源参数、视角可调节测试场景;(坐标不知道可采用此测试例子里的功能,利用键盘进行调节)

    namespace sharpGLTest11
    {
        public partial class Form1 : Form
        {
            private float rotation = 0.0f;
            private bool isRotate = false;
            private bool isLines = false;
            private bool isFrontView = false;
            private bool isLeftView = false;
            private bool isTopView = false;
            private bool isPerspective = true;
            private float[] lightPos = new float[] { -1, -3, 1, 1 };
            private float[] lightSphereColor = new float[] { 1f, 1f, 1f };
            private IList<float[]> lightColor = new List<float[]>();       //光源
            private double[] lookatValue = { 1, 1, 2, 0, 0, 0, 0, 1, 0 };  
            private IList<double[]> viewDefaultPos = new List<double[]>(); //视图
    
            public Form1()
            {
                InitializeComponent();
            }
    
            /*
             * 初始化
             * 
             * */
            private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
            {
                OpenGL gl = openGLControl.OpenGL;
    
                //四个视图的缺省位置
                viewDefaultPos.Add(new double[] { 1, 1, 2, 0, 0, 0, 0, 1, 0 });     //透视
                viewDefaultPos.Add(new double[] { 0, 0, 2, 0, 0, 0, 0, 1, 0 });     //前视 
                viewDefaultPos.Add(new double[] { 5, 0, 0, 0, 0, 0, 0, 1, 0 });     //左视
                viewDefaultPos.Add(new double[] { 0, 13, 0, -1, 0, 0, 0, 1, 0 });   //顶视
                lookatValue = (double[])viewDefaultPos[0].Clone();
                //
                lightColor.Add(new float[] { 1f, 1f, 1f, 1f });  //环境光(ambient light)
                lightColor.Add(new float[] { 1f, 1f, 1f, 1f });  //漫射光(diffuse light)
                lightColor.Add(new float[] { 1f, 1f, 1f, 1f });  //镜面反射光(specular light)
    
                setLightColor(gl);
                gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, lightPos); //设定灯光的位置
    
                gl.Enable(OpenGL.GL_LIGHTING);  //这两行是让灯光开,有效
                gl.Enable(OpenGL.GL_LIGHT0);    //
                //
                gl.ClearColor(0, 0, 0, 0);
            }
            //灯光
            private void setLightColor(OpenGL gl)
            {
                gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, lightColor[0]);   //环境光
                gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, lightColor[1]);   //漫射光
                gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_SPECULAR, lightColor[2]);  //镜面反射
            }
    
            /*
             * 画图
             * 
             * */
            private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e)
            {
                OpenGL gl = openGLControl.OpenGL;
                gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
                gl.LoadIdentity();
                gl.Rotate(rotation, 0.0f, 1.0f, 0.0f);
    
                drawGrid(gl);                                  //网格线
                DrawCube(ref gl, 1.5f, -1f, -2f, isLines);
                drawOneSphere(ref gl, -3, -2, -4, isLines);   //球体
                if (isRotate)
                    rotation += 3.0f;
            }
            void drawGrid(OpenGL gl)
            {
                //绘制过程
                gl.PushAttrib(OpenGL.GL_CURRENT_BIT);  //保存当前属性
                gl.PushMatrix();                        //压入堆栈
                gl.Translate(0f, -2f, 0f);
                gl.Color(0f, 0f, 1f);
    
                //在X,Z平面上绘制网格
                for (float i = -50; i <= 50; i += 1)
                {
                    //绘制线
                    gl.Begin(OpenGL.GL_LINES);
                    {
                        if (i == 0)
                            gl.Color(0f, 1f, 0f);
                        else
                            gl.Color(0f, 0f, 1f);
    
                        //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();
            }
            internal void DrawCube(ref OpenGL Gl, float xPos, float yPos, float zPos, bool isLine)
            {
                Gl.PushMatrix();
                Gl.Translate(xPos, yPos, zPos);
                if (isLine)
                    Gl.Begin(OpenGL.GL_LINE_STRIP);
                else
                    Gl.Begin(OpenGL.GL_POLYGON);
    
                /** 顶面 */
                Gl.Vertex(0.0f, 0.0f, 0.0f);
                Gl.Vertex(0.0f, 0.0f, -1.0f);
                Gl.Vertex(-1.0f, 0.0f, -1.0f);
                Gl.Vertex(-1.0f, 0.0f, 0.0f);
    
                /** 前面 */
                Gl.Vertex(0.0f, 0.0f, 0.0f);
                Gl.Vertex(-1.0f, 0.0f, 0.0f);
                Gl.Vertex(-1.0f, -1.0f, 0.0f);
                Gl.Vertex(0.0f, -1.0f, 0.0f);
    
                /** 右面 */
                Gl.Vertex(0.0f, 0.0f, 0.0f);
                Gl.Vertex(0.0f, -1.0f, 0.0f);
                Gl.Vertex(0.0f, -1.0f, -1.0f);
                Gl.Vertex(0.0f, 0.0f, -1.0f);
    
                /** 左面*/
                Gl.Vertex(-1.0f, 0.0f, 0.0f);
                Gl.Vertex(-1.0f, 0.0f, -1.0f);
                Gl.Vertex(-1.0f, -1.0f, -1.0f);
                Gl.Vertex(-1.0f, -1.0f, 0.0f);
    
                /** 底面 */
                Gl.Vertex(0.0f, 0.0f, 0.0f);
                Gl.Vertex(0.0f, -1.0f, -1.0f);
                Gl.Vertex(-1.0f, -1.0f, -1.0f);
                Gl.Vertex(-1.0f, -1.0f, 0.0f);
    
    
                /** 后面 */
                Gl.Vertex(0.0f, 0.0f, 0.0f);
                Gl.Vertex(-1.0f, 0.0f, -1.0f);
                Gl.Vertex(-1.0f, -1.0f, -1.0f);
                Gl.Vertex(0.0f, -1.0f, -1.0f);
                Gl.End();
                Gl.PopMatrix();
            }
            private void drawOneSphere(ref OpenGL gl, float xPos, float yPos, float zPos, bool isLine)
            {
                gl.PushMatrix();
                {
                    gl.Translate(xPos, yPos, zPos);
                    gl.Color(lightSphereColor);
                    drawSphere(gl, 1, 20, 10, isLine);
                }
                gl.PopMatrix();
            }
            void drawSphere(OpenGL gl, double radius, int segx, int segy, bool isLines)
            {
                gl.PushMatrix();
                gl.Translate(2f, 1f, 2f);
                var sphere = gl.NewQuadric();
                if (isLines)
                    gl.QuadricDrawStyle(sphere, OpenGL.GL_LINES);
                else
                    gl.QuadricDrawStyle(sphere, OpenGL.GL_QUADS);
                gl.QuadricNormals(sphere, OpenGL.GLU_SMOOTH);
                gl.QuadricOrientation(sphere, (int)OpenGL.GLU_OUTSIDE);
                gl.QuadricTexture(sphere, (int)OpenGL.GLU_FALSE);
                gl.Sphere(sphere, radius, segx, segy);
                gl.DeleteQuadric(sphere);
                gl.PopMatrix();
            }
    
            /*
             * 调整视角
             * 
             * */
            private void openGLControl_Resized(object sender, EventArgs e)
            {
    
                OpenGL gl = openGLControl.OpenGL;
                gl.MatrixMode(OpenGL.GL_PROJECTION);
                gl.LoadIdentity();
                gl.Perspective(40.0f, (double)Width / (double)Height, 0.01, 100.0);
    
                gl.LookAt(lookatValue[0], lookatValue[1], lookatValue[2],
                    lookatValue[3], lookatValue[4], lookatValue[5],
                    lookatValue[6], lookatValue[7], lookatValue[8]);
    
                gl.MatrixMode(OpenGL.GL_MODELVIEW);
                updateLabInfo();
            }
            /*
             * 将灯光位置、LookAt视角坐标显示
             * */
            private void updateLabInfo()
            {
                tbLightPos.Text = string.Format("{0},{1},{2},{3}", lightPos[0], lightPos[1], lightPos[2], lightPos[3]);
                tbLookAt.Text = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8}", lookatValue[0], lookatValue[1], lookatValue[2],
                    lookatValue[3], lookatValue[4], lookatValue[5], lookatValue[6], lookatValue[7], lookatValue[8]);
            }
    
            /*
             * 视口切换
             * */
            private void rbPerspective_CheckedChanged(object sender, EventArgs e)
            {
                switch (((RadioButton)sender).Name)
                {
                    case "rbPerspective":
                        isPerspective = !isPerspective;
                        isFrontView = false;
                        isTopView = false;
                        isLeftView = false;
                        break;
                    case "rbLeft":
                        isLeftView = !isLeftView;
                        isFrontView = false;
                        isPerspective = false;
                        isTopView = false;
                        break;
                    case "rbFront":
                        isFrontView = !isFrontView;
                        isTopView = false;
                        isPerspective = false;
                        isLeftView = false;
                        break;
                    case "rbTop":
                        isTopView = !isTopView;
                        isPerspective = false;
                        isLeftView = false;
                        isFrontView = false;
                        break;
                    default:
                        return;
                }
                setViewDefaultValue();
                openGLControl_Resized(null, null);
            }
            private void setViewDefaultValue()
            {
                if (isPerspective)
                {
                    lookatValue = (double[])viewDefaultPos[0].Clone();
                }
                else if (isFrontView)
                {
                    lookatValue = (double[])viewDefaultPos[1].Clone();
                }
                else if (isLeftView)
                {
                    lookatValue = (double[])viewDefaultPos[2].Clone();
                }
                else if (isTopView)
                {
                    lookatValue = (double[])viewDefaultPos[3].Clone();
                }
            }
    
            /*
             * 光源的颜色
             * */
            private void rbWhite_CheckedChanged(object sender, EventArgs e)
            {
                var rad = ((RadioButton)sender);
                var lightType = this.cbxLightType.SelectedIndex;
                if (rad.Checked)
                {
                    switch (rad.Name)
                    {
                        case "rbWhite":
                            lightColor[lightType][0] = 1f;
                            lightColor[lightType][1] = 1f;
                            lightColor[lightType][2] = 1f;
                            lightColor[lightType][3] = 1f;
                            break;
                        case "rbRed":
                            lightColor[lightType][0] = 1f;
                            lightColor[lightType][1] = 0f;
                            lightColor[lightType][2] = 0f;
                            lightColor[lightType][3] = 1f;
                            break;
                        case "rbGreen":
                            lightColor[lightType][0] = 0f;
                            lightColor[lightType][1] = 1f;
                            lightColor[lightType][2] = 0f;
                            lightColor[lightType][3] = 1f;
                            break;
                        case "rbBlue":
                            lightColor[lightType][0] = 0f;
                            lightColor[lightType][1] = 0f;
                            lightColor[lightType][2] = 1f;
                            lightColor[lightType][3] = 1f;
                            break;
                    }
                    setLightColor(openGLControl.OpenGL);
                }
            }
            //下拉框
            private void cbxLightType_SelectedIndexChanged(object sender, EventArgs e)
            {
                var lightType = this.cbxLightType.SelectedIndex;
                if (lightType >= 0)
                    judgeColor(lightColor[lightType]);
            }
            private void judgeColor(float[] color)
            {
                if (color[0] == 1f && color[1] == 1f && color[2] == 1f && color[3] == 1f)
                    rbWhite.Checked = true;
                else if (color[0] == 1f && color[1] == 0f && color[2] == 0f && color[3] == 1f)
                    rbRed.Checked = true;
                else if (color[0] == 0f && color[1] == 1f && color[2] == 0f && color[3] == 1f)
                    rbGreen.Checked = true;
                else if (color[0] == 0f && color[1] == 0f && color[2] == 1f && color[3] == 1f)
                    rbBlue.Checked = true;
            }
            //Form1事件,将下拉框选项改为默认选第一个
            private void SharpGLForm_Load(object sender, EventArgs e)
            {
                this.cbxLightType.SelectedIndex = 0;
                updateLabInfo();
            }
    
            /*
             * 视图旋转、线框显示、灯光关闭
             * */
            private void cbxRotate_CheckedChanged(object sender, EventArgs e)
            {
                var cbx = ((CheckBox)sender);
                switch (cbx.Name)
                {
                    case "cbxRotate":
                        isRotate = cbx.Checked;
                        break;
                    case "cbxLines":
                        isLines = cbx.Checked;
                        break;
                    case "cbxLightOff":
                        if (!cbx.Checked)
                            this.openGLControl.OpenGL.Enable(OpenGL.GL_LIGHT0);
                        else
                            this.openGLControl.OpenGL.Disable(OpenGL.GL_LIGHT0);
                        break;
                }
            }
    
            /*
             * 修改灯光位置、LookAt视角的确定按钮
             * */
            private void btnSetPos_Click(object sender, EventArgs e)
            {
                if (radioButton1.Checked)
                {
                    double[] ary = tbLookAt.Text.Split(',').Select(s => Convert.ToDouble(s)).ToArray();
                    lookatValue = ary;
                    openGLControl_Resized(null, null);
                }
                else
                {
                    float[] ary = tbLightPos.Text.Split(',').Select(s => Convert.ToSingle(s)).ToArray();
                    lightPos = ary;
                    openGLControl.OpenGL.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, ary);
                }
            }
    
            /*
             * 缺省位置
             * */
            private void btnDefaultPOS_Click(object sender, EventArgs e)
            {
                if (radioButton1.Checked)
                {
                    setViewDefaultValue();
                }
                else
                {
                    lightPos = new float[] { -1, -3, 1, 1 };
                    openGLControl.OpenGL.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, lightPos);
                }
                openGLControl_Resized(null, null);
            }
    
            /*
             * 单点位置变换——视图、光源
             * */
            private void btnQ_Click(object sender, EventArgs e)
            {
                moveObject(radioButton1.Checked ? 0 : 1, ((Button)sender).Name);
                openGLControl_Resized(null, null);
                openGLControl.OpenGL.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, lightPos);
            }
            private void moveObject(int obj, string keyName)
            {
                //obj==0移动视图
                switch (keyName)
                {
                    case "btnQ":
                        if (obj == 0) ++lookatValue[1];   //y
                        else
                            ++lightPos[1];
                        break;
                    case "btnE":
                        if (obj == 0) --lookatValue[1];
                        else
                            --lightPos[1];
                        break;
                    case "btnW":
                        if (obj == 0) --lookatValue[2];   //z
                        else
                            --lightPos[2];
                        break;
                    case "btnS":
                        if (obj == 0) ++lookatValue[2];
                        else
                            ++lightPos[2];
                        break;
                    case "btnA":
                        if (obj == 0) --lookatValue[0];  //X
                        else
                            --lightPos[0];
                        break;
                    case "btnD":
                        if (obj == 0) ++lookatValue[0];
                        else
                            ++lightPos[0];
                        break;
                }
            }
    
            /*
             * 添加键盘事件
             * 
             * */
            private void openGLControl_KeyDown(object sender, KeyEventArgs e)
            {
                Console.WriteLine("点击键盘!");
                string name = string.Empty;
                switch (e.KeyCode)
                {
                    case Keys.W:
                        name = "btnW";
                        break;
                    case Keys.A:
                        name = "btnA";
                        break;
                    case Keys.S:
                        name = "btnS";
                        break;
                    case Keys.D:
                        name = "btnD";
                        break;
                    case Keys.Q:
                        name = "btnQ";
                        break;
                    case Keys.E:
                        name = "btnE";
                        break;
                }
                moveObject(radioButton1.Checked ? 0 : 1, name);
                openGLControl_Resized(null, null);
            }
        }
    }
  • 相关阅读:
    模糊匹配
    UPDATE SET FROM WHERE 续
    SQL SERVER 中row_number用法
    临时表和表变量
    镜像
    经典行列转换
    表记录查询最快查询方式
    NULL不是数值
    自增长值
    JSON
  • 原文地址:https://www.cnblogs.com/lotuses/p/11360272.html
Copyright © 2011-2022 走看看