你的位置:首页 > 软件开发 > ASP.net > SharpGL学习笔记(十三) 光源例子:环绕二次曲面球体的光源

SharpGL学习笔记(十三) 光源例子:环绕二次曲面球体的光源

发布时间:2016-08-31 16:00:08
这是根据徐明亮《OpenGL游戏编程》书上光灯一节的一个例子改编的.从这个例子可以学习到二次曲面的参数设置,程序中提供了两个画球的函数,一个是用三角形画出来的,一个是二次曲面构成的.你会发现,跟三角形版本不同,二次曲面要做一些设定,否则画出来的球体无法接受光照. 先上代码: ...

SharpGL学习笔记(十三) 光源例子:环绕二次曲面球体的光源

这是根据徐明亮《OpenGL游戏编程》书上光灯一节的一个例子改编的.

从这个例子可以学习到二次曲面的参数设置,程序中提供了两个画球的函数,一个是用三角形画出来的,一个是二次曲面构成的.

你会发现,跟三角形版本不同,二次曲面要做一些设定,否则画出来的球体无法接受光照.

 

先上代码:

 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Draget='_blank'>wing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using SharpGL; 10  11 namespace light2 12 { 13   /// <summary> 14   /// 原创文章,出自"博客园, 猪悟能'S博客" : http://www.cnblogs.com/hackpig/ 15   /// </summary> 16   public partial class SharpGLForm : Form 17   { 18     private float rotation = 0.0f; 19     float m_bReadX, m_bReadY; 20     float m_bGreenX, m_bGreenY; 21     float m_bBlueX, m_bBlueY; 22  23     //3个光源位置 24     float[] lightPosR = new float[] { 0f, 0f, 2f, 1f }; 25     float[] lightPosG = new float[] { 0f, 0f, 2f, 1f }; 26     float[] lightPosB = new float[] { 0f, 0f, 2f, 1f }; 27  28     //3个光源漫射光 29     float[] diffLightR = { 1f, 0f, 0f, 1f }; 30     float[] diffLightG = { 0f, 1f, 0f, 1f }; 31     float[] diffLightB = { 0f, 0f, 1f, 1f }; 32  33     //定义3个光源我镜面光 34     float[] specLightR = { 1f, 0f, 0f, 1f }; 35     float[] specLightG = { 0f, 1f, 0f, 1f }; 36     float[] specLightB = { 0f, 0f, 1f, 1f }; 37  38     //默认的光源, 灰色光源,用于默认照明 39     float[] defDiffLight = new float[] { 0.8f, 0.8f, 0.8f, 1f }; 40     float[] defSpecLight = new float[] { 1f, 1f, 1f, 1f }; 41     float[] defLightPos = new float[] { 0f, 0f, 10f, 1f }; 42  43  44  45     public SharpGLForm() 46     { 47       InitializeComponent(); 48     } 49  50     private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e) 51     { 52       OpenGL gl = openGLControl.OpenGL; 53       gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT); 54       gl.LoadIdentity(); 55       gl.Rotate(rotation, 0.0f, 1.0f, 0.0f); 56  57       draw(gl); 58       rotation += 3.0f; 59  60       update(gl); 61     } 62  63     void update(OpenGL gl) 64     { 65       gl.Enable(OpenGL.GL_LIGHT1); 66       m_bReadX += 16; 67       m_bReadY += 12; 68       gl.Enable(OpenGL.GL_LIGHT2); 69       m_bGreenX += 10; 70       m_bGreenY += 6; 71       gl.Enable(OpenGL.GL_LIGHT3); 72       m_bBlueX += 2; 73       m_bBlueY += 4; 74     } 75  76     void draw(OpenGL gl) 77     { 78       gl.PushMatrix(); 79       //旋转红光 80       gl.Rotate(m_bReadX, 1f, 0f, 0f); 81       gl.Rotate(m_bReadY, 0f, 1f, 0f); 82       //设置红光的位置 83       gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_POSITION, lightPosR);   84       //绘制光球 85       gl.Translate(lightPosR[0], lightPosR[1], lightPosR[2]); 86       gl.Color(1f, 0f, 0f); 87       gl.PushAttrib(OpenGL.GL_LIGHTING_BIT); 88       gl.Disable(OpenGL.GL_LIGHTING); 89       drawSphere(gl,lightPosR[0], lightPosR[1], lightPosR[2],0.2f,10,10,false); 90       gl.Enable(OpenGL.GL_LIGHTING); 91       gl.PopAttrib(); 92       gl.PopMatrix(); 93  94  95       gl.PushMatrix(); 96       //旋转绿光 97       gl.Rotate(m_bGreenX, 1f, 0f, 0f); 98       gl.Rotate(m_bGreenY, 0f, 1f, 0f); 99       //设置绿光的位置100       gl.Light(OpenGL.GL_LIGHT2, OpenGL.GL_POSITION, lightPosG);101       //绘制光球102       gl.Translate(lightPosG[0], lightPosG[1], lightPosG[2]);103       gl.Color(0f, 1f, 0f);104       gl.PushAttrib(OpenGL.GL_LIGHTING_BIT);105       gl.Disable(OpenGL.GL_LIGHTING);106       drawSphere(gl, lightPosG[0], lightPosG[1], lightPosG[2], 0.2f, 10, 10 ,false);107       gl.Enable(OpenGL.GL_LIGHTING);108       gl.PopAttrib();109       gl.PopMatrix();110 111 112       gl.PushMatrix();113       //旋转蓝光114       gl.Rotate(m_bBlueX, 1f, 0f, 0f);115       gl.Rotate(m_bBlueY, 0f, 1f, 0f);116       //设置蓝光的位置117       gl.Light(OpenGL.GL_LIGHT3, OpenGL.GL_POSITION, lightPosB);118       //绘制光球119       gl.Translate(lightPosB[0], lightPosB[1], lightPosB[2]);120       gl.Color(0f, 0f, 1f);121       gl.PushAttrib(OpenGL.GL_LIGHTING_BIT);122       gl.Disable(OpenGL.GL_LIGHTING);123       drawSphere(gl, lightPosB[0], lightPosB[1], lightPosB[2], 0.2f, 10, 10,false);124       gl.Enable(OpenGL.GL_LIGHTING);125       gl.PopAttrib();126       gl.PopMatrix();127 128 129       //绘制球体130       gl.PushMatrix();131       gl.Rotate(rotation, 1f, 0f, 0f);132       gl.Rotate(rotation, 0f, 1f, 0f);133       gl.Rotate(rotation, 0f, 0f, 1f);134       drawSphere(gl, 0, 0, 0, 3, 40, 40,false);135 136       gl.PopMatrix();137 138       gl.Flush();139 140     }141 142     //二次曲面球体143     void drawSphere(OpenGL gl,float x,float y,float z, double radius, int segx, int segy, bool isLines)144     {145       gl.PushMatrix();146       gl.Translate(x, y, z);147       var sphere = gl.NewQuadric();148       if (isLines)149         gl.QuadricDrawStyle(sphere, OpenGL.GL_LINES);150       else151         gl.QuadricDrawStyle(sphere, OpenGL.GL_QUADS);152       gl.QuadricNormals(sphere, OpenGL.GLU_NONE);  //GLU_NONE,GLU_FLAT,GLU_SMOOTH153       gl.QuadricOrientation(sphere, (int)OpenGL.GLU_OUTSIDE); //GLU_OUTSIDE,GLU_INSIDE154       gl.QuadricTexture(sphere, (int)OpenGL.GLU_FALSE); //GL_TRUE,GLU_FALSE155       gl.Sphere(sphere, radius, segx, segy);156       gl.DeleteQuadric(sphere);157       gl.PopMatrix();158     }159 160     //球心坐标为(x,y,z),球的半径为radius,M,N分别表示球体的横纵向被分成多少份161     void drawSphere1(OpenGL gl, float xx, float yy, float zz, float radius, float M, float N,bool isLines)162     {163       const float PI = 3.1415926f;164       float step_z = (float)Math.PI / M;165       float step_xy = 2 * PI / N;166       float[] x = new float[4] { 0, 0, 0, 0 };167       float[] y = new float[4] { 0, 0, 0, 0 };168       float[] z = new float[4] { 0, 0, 0, 0 };169 170       float angle_z = 0.0f;171       float angle_xy = 0.0f;172       int i = 0, j = 0;173       gl.Begin(OpenGL.GL_QUADS);174       for (i = 0; i < M; i++)175       {176         angle_z = i * step_z;177         for (j = 0; j < N; j++)178         {179           angle_xy = j * step_xy;180 181           x[0] = (float)(radius * Math.Sin(angle_z) * Math.Cos(angle_xy));182           y[0] = (float)(radius * Math.Sin(angle_z) * Math.Sin(angle_xy));183           z[0] = (float)(radius * Math.Cos(angle_z));184 185           x[1] = (float)(radius * Math.Sin(angle_z + step_z) * Math.Cos(angle_xy));186           y[1] = (float)(radius * Math.Sin(angle_z + step_z) * Math.Sin(angle_xy));187           z[1] = (float)(radius * Math.Cos(angle_z + step_z));188 189           x[2] = (float)(radius * Math.Sin(angle_z + step_z) * Math.Cos(angle_xy + step_xy));190           y[2] = (float)(radius * Math.Sin(angle_z + step_z) * Math.Sin(angle_xy + step_xy));191           z[2] = (float)(radius * Math.Cos(angle_z + step_z));192 193           x[3] = (float)(radius * Math.Sin(angle_z) * Math.Cos(angle_xy + step_xy));194           y[3] = (float)(radius * Math.Sin(angle_z) * Math.Sin(angle_xy + step_xy));195           z[3] = (float)(radius * Math.Cos(angle_z));196 197           for (int k = 0; k < 4; k++)198           {199             gl.Vertex(xx + x[k], yy + y[k], zz + z[k]);200           }201         }202       }203       gl.End();204     }205 206     private void openGLControl_OpenGLInitialized(object sender, EventArgs e)207     {208       OpenGL gl = openGLControl.OpenGL;209       setLight(gl);210       //gl.Enable(OpenGL.GL_NORMALIZE);211       gl.ClearColor(0, 0, 0, 0);212     }213 214     private void setLight(OpenGL gl)215     {216       //0号灯光,默认灯光217       gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, defDiffLight);218       gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_SPECULAR, defSpecLight);219       gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, defLightPos);220 221       //1号灯光222       gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_DIFFUSE, diffLightR);223       gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_SPECULAR, specLightR);224       gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_POSITION, lightPosR);225 226       //2号灯光227       gl.Light(OpenGL.GL_LIGHT2, OpenGL.GL_DIFFUSE, diffLightG);228       gl.Light(OpenGL.GL_LIGHT2, OpenGL.GL_SPECULAR, specLightG);229       gl.Light(OpenGL.GL_LIGHT2, OpenGL.GL_POSITION, lightPosG);230 231       //3号灯光232       gl.Light(OpenGL.GL_LIGHT3, OpenGL.GL_DIFFUSE, diffLightB);233       gl.Light(OpenGL.GL_LIGHT3, OpenGL.GL_SPECULAR, specLightB);234       gl.Light(OpenGL.GL_LIGHT3, OpenGL.GL_POSITION, lightPosB);235 236       gl.Enable(OpenGL.GL_LIGHTING);237       gl.Enable(OpenGL.GL_LIGHT0); //启用默认光源238 239     }240 241     private void openGLControl_Resized(object sender, EventArgs e)242     {243       OpenGL gl = openGLControl.OpenGL;244       gl.MatrixMode(OpenGL.GL_PROJECTION);245       gl.LoadIdentity();246       gl.Perspective(70.0f, (double)Width / (double)Height, 0.01, 100.0);247       gl.LookAt(-5, 5, -5, 0, 0, 0, 0, 1, 0);248       gl.MatrixMode(OpenGL.GL_MODELVIEW);249     }250     251   }252 }

原标题:SharpGL学习笔记(十三) 光源例子:环绕二次曲面球体的光源

关键词:

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录