13事例十三:光源例子:环绕二次曲面球体的光源
Posted lotuses
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了13事例十三:光源例子:环绕二次曲面球体的光源相关的知识,希望对你有一定的参考价值。
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事例十三:光源例子:环绕二次曲面球体的光源的主要内容,如果未能解决你的问题,请参考以下文章