23.在单元测试中添加光源
为了在单元测试中显示光照效果,现将引擎中单元测试使用的场景类defaultScene.cs的代码修改为以下内容:
namespace StunEngine { class defaultScene:Scene { public FpsCameraController fpsCamCtrl; //一个长方体构成的地板作为参照物 private CubeSceneNode floor = null; //单向光源 Light sunLight; // 切换单向光源的移动 bool sunLightMove = false; // 点光源 Light pointLight; // 切换点光源的移动 bool pointLightMove = false; //聚光灯 Light spotLight; // 切换聚光灯的移动 bool spotLightMove = false; // 第二个点光源 Light pointLight2; //代表光源的模型 ModelSceneNode sunModel = null; ModelSceneNode pointLightModel = null; ModelSceneNode pointLightModel2 = null; ModelSceneNode spotLightModel = null; Vector3 position; Vector3 scale; Vector3 color; Quaternion rotation; float rotationAngle; ////// 构造函数 /// public defaultScene(StunXnaGE engine) : base(engine, "default") { } public override void Initialize() { base.Initialize(); //添加一个长方体代表地面作为参照物 floor = new CubeSceneNode(engine, this, "Textures//Grid", new Vector2(4f, 4f), null, Vector2.Zero); AddNode(floor); scale = new Vector3(20f, 0.5f, 20f); floor.Pose.SetScale(ref scale); //----------------------------------- // 创建单向光 //----------------------------------- //单向光源颜色设置为灰白色,位置为(0, 5, 10),单向光的位置是无意义的,实际设置的是它的光线方向,但设置位置比较符合习惯 color = new Vector3(0.8f, 0.8f, 0.8f); position = new Vector3(0, 5, 10); // 添加单向光源 sunLight = new Light(engine, color, -position); AddLight(sunLight); //添加一个代表带单向光源的箭头模型 sunModel = new ModelSceneNode(engine, this, "Models//arrow"); AddNode(sunModel); sunModel.Material.CurrentTechniqueName = "SimpleTextured"; sunModel.Material.DiffuseTextureName = null; sunModel.Material.DiffuseColor = color; sunModel.Pose.SetPosition(ref position); //将箭头放大2倍 scale = new Vector3(2.0f, 2.0f, 2.0f); sunModel.Pose.SetScale(ref scale); rotation = Quaternion.CreateFromYawPitchRoll(0, 3 * MathHelper.PiOver4, 0); sunModel.Pose.SetRotation(ref rotation); //----------------------------------- // 创建点光源 //----------------------------------- //点光源颜色设置为红色,位置为(-8, 5, 0) color = new Vector3(1.0f, 0.0f, 0f); position = new Vector3(-8, 5, 0); //添加点光源 pointLight = new Light(engine, color, position, 20.0f, 2.0f); AddLight(pointLight); //添加一个代表点光源的球体模型 pointLightModel = new ModelSceneNode(engine, this, "Models//SphereLowPoly"); AddNode(pointLightModel); pointLightModel.Pose.SetPosition(ref position); pointLightModel.Material.CurrentTechniqueName = "SimpleTextured"; pointLightModel.Material.DiffuseTextureName = null; pointLightModel.Material.DiffuseColor = color; //将球缩小到0.3倍 scale = new Vector3(0.3f, 0.3f, 0.3f); pointLightModel.Pose.SetScale(ref scale); //----------------------------------- // 创建聚光灯 //----------------------------------- //将聚光灯的颜色设置为蓝色,位置为(0, 8, 0) color = new Vector3(0.0f, 0.0f, 1.0f); position = new Vector3(0, 8, 0); //添加一个聚光灯光源,光线方向竖直向下 spotLight = new Light(engine, color, position, new Vector3(0, -1, 0), 15f, 1f, MathHelper.Pi /6.0f, MathHelper.Pi/3.0f); AddLight(spotLight); //添加一个代表聚光灯的圆锥体模型 spotLightModel = new ModelSceneNode(engine, this, "Models//Cone"); AddNode(spotLightModel); spotLightModel.Material.CurrentTechniqueName = "SimpleTextured"; spotLightModel.Material.DiffuseTextureName = null; spotLightModel.Material.DiffuseColor = color; spotLightModel.Pose.SetPosition(ref position); spotLightModel.Pose.SetScale(ref scale); rotation = Quaternion.CreateFromYawPitchRoll(0, MathHelper.PiOver2, 0); spotLightModel.Pose.SetRotation(ref rotation); //----------------------------------- // 创建相机 //----------------------------------- Vector3 cameraPosition = new Vector3(0, 5, 20); CameraSceneNode Camera = new CameraSceneNode(engine, this, cameraPosition, cameraPosition + Vector3.Forward); Camera.Initialize(); Camera.FOV = MathHelper.PiOver4; this.Camera = Camera; //----------------------------------- // 创建fps相机控制器 //----------------------------------- fpsCamCtrl = new FpsCameraController(engine); fpsCamCtrl.Elevation = 90; Camera.AttachController(fpsCamCtrl); //设置环境光颜色 this.AmbientColor = new Vector3(0.1f, 0.1f, 0.1f); //设置雾化参数 this.FogEnabled = true; this.FogStart = 50.0f; this.FogEnd = 100.0f; this.FogColor = new Color(1.0f, 1.0f, 1.0f).ToVector4(); } public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen) { float time = (float)gameTime.TotalGameTime.TotalMilliseconds / 1000.0f; //即一秒种转动的角度为45度 rotationAngle = time* 45 % 360; float rotationRadians = MathHelper.ToRadians(rotationAngle); //在高度为5的XZ平面上做半径为10的顺时针圆周运动 position = new Vector3(10 * (float)Math.Sin(-rotationRadians), 5.0f, 10 * (float)Math.Cos(-rotationRadians)); if (sunLightMove) { //设置单向光源位置 sunLight.Position = position; //设置箭头模型位置 sunModel.Pose.SetPosition(ref position); //设置箭头模型旋转 rotation = Quaternion.CreateFromYawPitchRoll(-(float)Math.Sin(rotationRadians), 3 * MathHelper.PiOver4, 0); sunModel.Pose.SetRotation(ref rotation); } //在高度为5的XZ平面上做半径为8的逆时针圆周运动 position = new Vector3(8 * (float)Math.Sin(rotationRadians), 5.0f, 8 * (float)Math.Cos(rotationRadians)); if (pointLightMove) { //设置点光源位置 pointLight.Position = position; //设置球模型位置 pointLightModel.Pose.SetPosition(ref position); } //让聚光灯光照方向左右旋转 Matrix lightRotation = Matrix.CreateRotationZ((float)Math.Sin(rotationRadians)); Vector3 lightDirection = Vector3.Transform(new Vector3(0, -1, 0), lightRotation); if (spotLightMove) { //设置聚光灯光线旋转 spotLight.Direction = lightDirection; //圆锥模型也随着旋转 Quaternion qu = Quaternion.CreateFromAxisAngle(Vector3.Right, MathHelper.PiOver2) * Quaternion.CreateFromAxisAngle(Vector3.Up, (float)Math.Sin(rotationRadians)); spotLightModel.Pose.SetRotation(ref qu); } //按数字键盘1键切换单向光的开关 if ((!(Input.Keyboard.IsKeyDown(Keys.LeftControl) || Input.Keyboard.IsKeyDown(Keys.RightControl)))&&Input.KeyboardKeyJustPressed(Keys.NumPad1)) { sunLight.Enabled = !sunLight.Enabled; sunModel.Visible = !sunModel.Visible; } //按住Control+数字键盘1键切换单向光源的移动 if ((Input.Keyboard.IsKeyDown(Keys.LeftControl) || Input.Keyboard.IsKeyDown(Keys.RightControl)) && Input.KeyboardKeyJustPressed(Keys.NumPad1)) { sunLightMove = !sunLightMove; } //按数字键盘2键切换点光源的开关 if ((!(Input.Keyboard.IsKeyDown(Keys.LeftControl) || Input.Keyboard.IsKeyDown(Keys.RightControl)))&&Input.KeyboardKeyJustPressed(Keys.NumPad2 )) { pointLight.Enabled = !pointLight.Enabled; pointLightModel.Visible = !pointLightModel.Visible; } //按住Control+数字键盘2键切换点光源的移动 if ((Input.Keyboard .IsKeyDown(Keys.LeftControl ) || Input.Keyboard.IsKeyDown(Keys.RightControl)) && Input.KeyboardKeyJustPressed(Keys.NumPad2)) { pointLightMove = !pointLightMove; } //按数字键盘3键切换聚光灯的开关 if ((!(Input.Keyboard.IsKeyDown(Keys.LeftControl) || Input.Keyboard.IsKeyDown(Keys.RightControl))) && Input.KeyboardKeyJustPressed(Keys.NumPad3)) { spotLight.Enabled = !spotLight.Enabled; spotLightModel.Visible = !spotLightModel.Visible; } //按住Control+数字键盘3键切换聚光灯的移动 if ((Input.Keyboard.IsKeyDown(Keys.LeftControl) || Input.Keyboard.IsKeyDown(Keys.RightControl)) && Input.KeyboardKeyJustPressed(Keys.NumPad3)) { spotLightMove = !spotLightMove ; } //按+键添加一个点光源 if (Input.KeyboardKeyJustPressed(Keys.Add )) { if (pointLight2 == null) { //点光源颜色设置为绿色,位置为(-4, 5, 0) color = new Vector3(0.0f, 1.0f, 0.0f); position = new Vector3(4, 5, 0); //添加点光源 pointLight2 = new Light(engine, color, position, 25.0f, 1.0f); AddLight(pointLight2); //添加一个代表点光源的球体模型 pointLightModel2 = new ModelSceneNode(engine, this, "Models//SphereLowPoly"); AddNode(pointLightModel2); pointLightModel2.Pose.SetPosition(ref position); pointLightModel2.Material.CurrentTechniqueName = "SimpleTextured"; pointLightModel2.Material.DiffuseTextureName = null; pointLightModel2.Material.DiffuseColor = color; //将球缩小到0.2倍 scale = new Vector3(0.2f, 0.2f, 0.2f); pointLightModel2.Pose.SetScale(ref scale); } } //按-键移除一个点光源 if (Input.KeyboardKeyJustPressed(Keys.Subtract )) { if (pointLight2 != null) { RemoveLastLight(); RemoveNode(pointLightModel2); pointLight2 = null; } } base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen); } } }
具体解释请看代码中的注释。上述代码在场景中添加了3个光源,分别是单向光源、点光源和聚光灯。实现的效果是按数字键盘1键切换单向光的开关,按Control+1键切换单向光源的运动,单向光源在5个单位的高度上做半径为10的顺时针旋转。按数字键盘2键切换点光源的开关,按Control+2键切换点光源的运动,点光源在5个单位的高度上做半径为8的逆时针旋转。按数字键盘3键切换聚光灯的开关,按Control+3键切换聚光灯光照方向的移动,聚光灯光照方向左右旋转。按+键在场景中添加第4个蓝色的点光源,按-键移除这个光源。程序截图如下:
文件下载(已下载 1332 次)
发布时间:2010/4/23 下午12:56:49 阅读次数:5800