码迷,mamicode.com
首页 > 其他好文 > 详细

13、事例十三:光源例子:环绕二次曲面球体的光源(二)

时间:2019-08-15 21:04:08      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:use   lines   bsp   nta   defs   disable   mat   push   entity   

namespace sharpGLTest13
{
    public partial class Form1 : Form
    {
        private float rotation = 0.0f;
        float m_bReadX, m_bReadY;
        float m_bGreenX, m_bGreenY;
        float m_bBlueX, m_bBlueY;

        //3个光源位置
        float[] lightPosR = new float[] { 0f, 0f, 2f, 1f };
        float[] lightPosG = new float[] { 0f, 0f, 2f, 1f };
        float[] lightPosB = new float[] { 0f, 0f, 2f, 1f };

        //3个光源漫射光
        float[] diffLightR = { 1f, 0f, 0f, 1f };
        float[] diffLightG = { 0f, 1f, 0f, 1f };
        float[] diffLightB = { 0f, 0f, 1f, 1f };

        //定义3个光源我镜面光
        float[] specLightR = { 1f, 0f, 0f, 1f };
        float[] specLightG = { 0f, 1f, 0f, 1f };
        float[] specLightB = { 0f, 0f, 1f, 1f };

        //默认的光源, 灰色光源,用于默认照明
        float[] defDiffLight = new float[] { 0.8f, 0.8f, 0.8f, 1f };
        float[] defSpecLight = new float[] { 1f, 1f, 1f, 1f };
        float[] defLightPos = new float[] { 0f, 0f, 10f, 1f };

        public Form1()
        {
            InitializeComponent();
        }

        private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
        {
            OpenGL gl = openGLControl.OpenGL;
            setLight(gl);
            //gl.Enable(OpenGL.GL_NORMALIZE);
            gl.ClearColor(0, 0, 0, 0);
        }
        private void setLight(OpenGL gl)
        {
            //0号灯光,默认灯光
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, defDiffLight);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_SPECULAR, defSpecLight);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, defLightPos);

            //1号灯光
            gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_DIFFUSE, diffLightR);
            gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_SPECULAR, specLightR);
            gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_POSITION, lightPosR);

            //2号灯光
            gl.Light(OpenGL.GL_LIGHT2, OpenGL.GL_DIFFUSE, diffLightG);
            gl.Light(OpenGL.GL_LIGHT2, OpenGL.GL_SPECULAR, specLightG);
            gl.Light(OpenGL.GL_LIGHT2, OpenGL.GL_POSITION, lightPosG);

            //3号灯光
            gl.Light(OpenGL.GL_LIGHT3, OpenGL.GL_DIFFUSE, diffLightB);
            gl.Light(OpenGL.GL_LIGHT3, OpenGL.GL_SPECULAR, specLightB);
            gl.Light(OpenGL.GL_LIGHT3, OpenGL.GL_POSITION, lightPosB);

            gl.Enable(OpenGL.GL_LIGHTING);
            gl.Enable(OpenGL.GL_LIGHT0);  //启用默认光源

        }

        private void openGLControl_Resized(object sender, EventArgs e)
        {
            OpenGL gl = openGLControl.OpenGL;
            gl.MatrixMode(OpenGL.GL_PROJECTION);
            gl.LoadIdentity();
            gl.Perspective(70.0f, (double)Width / (double)Height, 0.01, 100.0);
            gl.LookAt(-5, 5, -5, 0, 0, 0, 0, 1, 0);
            gl.MatrixMode(OpenGL.GL_MODELVIEW);
        }

        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);

            draw(gl);
            rotation += 3.0f;

            update(gl);
        }

        void update(OpenGL gl)
        {
            gl.Enable(OpenGL.GL_LIGHT1);
            m_bReadX += 16;
            m_bReadY += 12;
            gl.Enable(OpenGL.GL_LIGHT2);
            m_bGreenX += 10;
            m_bGreenY += 6;
            gl.Enable(OpenGL.GL_LIGHT3);
            m_bBlueX += 2;
            m_bBlueY += 4;
        }

        void draw(OpenGL gl)
        {
            gl.PushMatrix();
            //旋转红光
            gl.Rotate(m_bReadX, 1f, 0f, 0f);
            gl.Rotate(m_bReadY, 0f, 1f, 0f);
            //设置红光的位置
            gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_POSITION, lightPosR);
            //绘制光球
            gl.Translate(lightPosR[0], lightPosR[1], lightPosR[2]);
            gl.Color(1f, 0f, 0f);
            gl.PushAttrib(OpenGL.GL_LIGHTING_BIT);
            gl.Disable(OpenGL.GL_LIGHTING);
            drawSphere(gl, lightPosR[0], lightPosR[1], lightPosR[2], 0.2f, 10, 10, false);
            gl.Enable(OpenGL.GL_LIGHTING);
            gl.PopAttrib();
            gl.PopMatrix();


            gl.PushMatrix();
            //旋转绿光
            gl.Rotate(m_bGreenX, 1f, 0f, 0f);
            gl.Rotate(m_bGreenY, 0f, 1f, 0f);
            //设置绿光的位置
            gl.Light(OpenGL.GL_LIGHT2, OpenGL.GL_POSITION, lightPosG);
            //绘制光球
            gl.Translate(lightPosG[0], lightPosG[1], lightPosG[2]);
            gl.Color(0f, 1f, 0f);
            gl.PushAttrib(OpenGL.GL_LIGHTING_BIT);
            gl.Disable(OpenGL.GL_LIGHTING);
            drawSphere(gl, lightPosG[0], lightPosG[1], lightPosG[2], 0.2f, 10, 10, false);
            gl.Enable(OpenGL.GL_LIGHTING);
            gl.PopAttrib();
            gl.PopMatrix();


            gl.PushMatrix();
            //旋转蓝光
            gl.Rotate(m_bBlueX, 1f, 0f, 0f);
            gl.Rotate(m_bBlueY, 0f, 1f, 0f);
            //设置蓝光的位置
            gl.Light(OpenGL.GL_LIGHT3, OpenGL.GL_POSITION, lightPosB);
            //绘制光球
            gl.Translate(lightPosB[0], lightPosB[1], lightPosB[2]);
            gl.Color(0f, 0f, 1f);
            gl.PushAttrib(OpenGL.GL_LIGHTING_BIT);
            gl.Disable(OpenGL.GL_LIGHTING);
            drawSphere(gl, lightPosB[0], lightPosB[1], lightPosB[2], 0.2f, 10, 10, false);
            gl.Enable(OpenGL.GL_LIGHTING);
            gl.PopAttrib();
            gl.PopMatrix();


            //绘制球体
            gl.PushMatrix();
            gl.Rotate(rotation, 1f, 0f, 0f);
            gl.Rotate(rotation, 0f, 1f, 0f);
            gl.Rotate(rotation, 0f, 0f, 1f);
            drawSphere(gl, 0, 0, 0, 3, 40, 40, false);

            gl.PopMatrix();

            gl.Flush();

        }
        //二次曲面球体
        void drawSphere(OpenGL gl, float x, float y, float z, double radius, int segx, int segy, bool isLines)
        {
            gl.PushMatrix();
            gl.Translate(x, y, z);
            var sphere = gl.NewQuadric();

            /*
             * QuadricDrawStyle(IntPtr quadObject, uint drawStyle);
             * 第一个参数是二次方程对象状态的指针
             * 第二个参数的枚举值:GLU_FILL(二次方程对象画成实体)、GLU_LINE(二次方程对象画成线框)
             *      GLU_POINT(二次方程对象画成一组顶点的集合)、GLU_SILHOUETTE(类似于线框,但相邻的多边形的边不被绘制)
             * */
            if (isLines)
                gl.QuadricDrawStyle(sphere, OpenGL.GL_LINES);
            else
                gl.QuadricDrawStyle(sphere, OpenGL.GL_QUADS);

            /*
             * QuadricNormals(IntPtr quadricObject, uint normals);
             * 这个函数指定二次方程对象如何生成法线。
             * 第二个参数可以是:GLU_NONE不生成法线,GLU_FLAT扁平法线,GLU_SMOOTH平滑法线。
             * 
             * */
            gl.QuadricNormals(sphere, OpenGL.GLU_NONE);   //GLU_NONE,GLU_FLAT,GLU_SMOOTH

            /*
             * QuadricOrientation(IntPtr quadricObject, int orientation);
             * 这个函数可以指定法线的朝向,指向外面还是只想里面。
             * orientation可以是GLU_OUTSIDE或者是GLU_INSIDE这两个值。
             * OpenGL默认是以GL_CCW逆时针为正方向的
             * 
             * */
            gl.QuadricOrientation(sphere, (int)OpenGL.GLU_OUTSIDE);  //GLU_OUTSIDE,GLU_INSIDE

            /*
             * QuadricTexture(IntPtr quadricObject, int textureCoords)
             * 这个函数可以指定二次方程表面的纹理坐标
             * textureCoords这个参数可以是GL_TRUE或者GL_FALSE.
             * 当为球体和圆柱体生成纹理坐标时,纹理是对称地环绕在球体和圆柱体的表面的
             * 如果应用到圆盘上,那么纹理的中心就是圆盘的中心,然后以线性插值的方式扩展到圆盘的边界
             * 
             * */
            gl.QuadricTexture(sphere, (int)OpenGL.GLU_FALSE);  //GL_TRUE,GLU_FALSE
            gl.Sphere(sphere, radius, segx, segy);
            gl.DeleteQuadric(sphere);
            gl.PopMatrix();
        }

        /*
         * 以点画圆
         * 
         * */
        //球心坐标为(x,y,z),球的半径为radius,M,N分别表示球体的横纵向被分成多少份
        void drawSphere1(OpenGL gl, float xx, float yy, float zz, float radius, float M, float N, bool isLines)
        {
            const float PI = 3.1415926f;
            float step_z = (float)Math.PI / M;
            float step_xy = 2 * PI / N;
            float[] x = new float[4] { 0, 0, 0, 0 };
            float[] y = new float[4] { 0, 0, 0, 0 };
            float[] z = new float[4] { 0, 0, 0, 0 };

            float angle_z = 0.0f;
            float angle_xy = 0.0f;
            int i = 0, j = 0;
            gl.Begin(OpenGL.GL_QUADS);
            for (i = 0; i < M; i++)
            {
                angle_z = i * step_z;
                for (j = 0; j < N; j++)
                {
                    angle_xy = j * step_xy;

                    x[0] = (float)(radius * Math.Sin(angle_z) * Math.Cos(angle_xy));
                    y[0] = (float)(radius * Math.Sin(angle_z) * Math.Sin(angle_xy));
                    z[0] = (float)(radius * Math.Cos(angle_z));

                    x[1] = (float)(radius * Math.Sin(angle_z + step_z) * Math.Cos(angle_xy));
                    y[1] = (float)(radius * Math.Sin(angle_z + step_z) * Math.Sin(angle_xy));
                    z[1] = (float)(radius * Math.Cos(angle_z + step_z));

                    x[2] = (float)(radius * Math.Sin(angle_z + step_z) * Math.Cos(angle_xy + step_xy));
                    y[2] = (float)(radius * Math.Sin(angle_z + step_z) * Math.Sin(angle_xy + step_xy));
                    z[2] = (float)(radius * Math.Cos(angle_z + step_z));

                    x[3] = (float)(radius * Math.Sin(angle_z) * Math.Cos(angle_xy + step_xy));
                    y[3] = (float)(radius * Math.Sin(angle_z) * Math.Sin(angle_xy + step_xy));
                    z[3] = (float)(radius * Math.Cos(angle_z));

                    for (int k = 0; k < 4; k++)
                    {
                        gl.Vertex(xx + x[k], yy + y[k], zz + z[k]);
                    }
                }
            }
            gl.End();
        }
    }
}

 

13、事例十三:光源例子:环绕二次曲面球体的光源(二)

标签:use   lines   bsp   nta   defs   disable   mat   push   entity   

原文地址:https://www.cnblogs.com/lotuses/p/11360292.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!