文章目錄
- 1 初始化材質、光照、紋理和星球
- 2 繪製星球
- 3 通過OpenFileDialog替換紋理
- 4 通過拖拽替換紋理
SharpGL(Opengl)入門之紋理星球
PS:SharpGL是C#對Opengl的封裝,不瞭解SharpGL的同學可以去www.codeproject.com搜尋SharpGL。
做個小例子,能夠載入各種圖片到球形的星球上顯示,星球自動旋轉,可用WSAD和滑鼠控制視角,用QE控制上下,文末附原始碼和release程式。
A picture paints a thousand sentences.
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。
4.2 事件代碼
為OpenGLControl添加DragEnter和DragDrop事件。
代碼如下。
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