SharpGL(Opengl)入門之紋理星球


SharpGL(Opengl)入門之紋理星球

PS:SharpGL是C#對Opengl的封裝,不了解SharpGL的同學可以去www.codeproject.com搜索SharpGL。

做個小例子,能夠加載各種圖片到球形的星球上顯示,星球自動旋轉,可用WSAD和鼠標控制視角,用QE控制上下,文末附源代碼和release程序。

A picture paints a thousand sentences.

clip_image002image

clip_image004

PS:旋轉的地球GIF在這里:http://images.cnblogs.com/cnblogs_com/bitzhuwei/482613/o_earth.gif

旋轉的月球GIF在這里:http://images.cnblogs.com/cnblogs_com/bitzhuwei/482613/o_moon.gif

1 初始化材質、光照、紋理和星球

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

            gl.ClearColor(0, 0, 0, 0);
            gl.ShadeModel(OpenGL.GL_SMOOTH);
            //初始化材質
            var mat_specular = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
            var mat_ambient = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
            var mat_diffuse = new float[] { 2.0f, 2.0f, 2.0f, 0.1f };
            var mat_shininess = new float[] { 100.0f };
            gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SPECULAR, mat_specular);
            gl.Material(OpenGL.GL_FRONT, OpenGL.GL_AMBIENT, mat_ambient);
            gl.Material(OpenGL.GL_FRONT, OpenGL.GL_DIFFUSE, mat_diffuse);
            gl.Material(OpenGL.GL_FRONT, OpenGL.GL_SHININESS, mat_shininess);
            //初始化光照
            var ambientLight = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
            var diffuseLight = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };    
            var posLight0 = new float[] { 2.0f, 0.1f, 0.0f, 0.0f };
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, ambientLight);
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, diffuseLight); 
            gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, posLight0);
            //初始化紋理
            texture = new SharpGL.SceneGraph.Assets.Texture();
            texture.Create(gl, "Data/earth.bmp");
            //初始化星球
            ptrBall = gl.NewQuadric();                    
            gl.QuadricNormals(ptrBall, OpenGL.GL_SMOOTH);
            gl.QuadricTexture(ptrBall, (int)(OpenGL.GL_TRUE));

            gl.Enable(OpenGL.GL_TEXTURE_2D);
            gl.Enable(OpenGL.GL_LIGHTING);
            gl.Enable(OpenGL.GL_LIGHT0);
            gl.Enable(OpenGL.GL_LIGHT1);
            gl.Enable(OpenGL.GL_DEPTH_TEST);
        }

2 繪制星球

private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e)
        {
            if (this.texture != null)
            {
                OpenGL gl = openGLControl.OpenGL;

                gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
                
                gl.LoadIdentity();
                gl.Scale(3.6, 3.6, 3.6);//放大到3.6倍
                gl.Rotate(90, 1.0f, 0, 0);//繞X軸旋轉90度
                gl.Rotate(-rotation, 0.0f, 0.0f, 1.0f);//饒Z軸旋轉
                gl.Sphere(ptrBall, 1.0f, 100, 100);//繪制星球

                rotation += 3.0f;
            }
        }

3 通過OpenFileDialog替換紋理

private void lblTextureImage_Click(object sender, EventArgs e)
        {
            if (openTextureImage.ShowDialog()== System.Windows.Forms.DialogResult.OK)
            {
                UpdateTextureImage(openTextureImage.FileName);
            }
        }

        private void UpdateTextureImage(string filename)
        {
            var gl = this.openGLControl.OpenGL;
            if (this.texture != null)
            {
                this.texture.Destroy(gl);
                this.texture.Create(gl, filename);
                this.lblTextureImage.Text = (new FileInfo(filename)).Name;
            }
        }

4 通過拖拽替換紋理

4.1 屬性設置

將OpenGLControl的AllowDrop屬性設置為True。

clip_image005

4.2 事件代碼

為OpenGLControl添加DragEnter和DragDrop事件。

clip_image006

代碼如下。

private void openGLControl_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.All;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void openGLControl_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                var item = (string[])e.Data.GetData(DataFormats.FileDrop);
                UpdateTextureImage(item[0]);
            }
        }

Enjoy!

完整源代碼在此:bitzhuwei.SolarSystem.TexturedEarth.zip

release版程序在此:紋理星球-release.zip


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM