/// <summary> /// Allows the game component to draw itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Draw(GameTime gameTime) { Matrix world = fCamera.Camera.WorldMatrix; Matrix view = fCamera.Camera.ViewMatrix; Matrix projection = fCamera.Camera.ProjectionMatrix; if (!fHalted) { fWorldAngle += Convert.ToSingle(gameTime.ElapsedGameTime.TotalSeconds * 1.5f); } world = Matrix.CreateRotationY(fWorldAngle); GraphicsDevice.BlendState = BlendState.NonPremultiplied; GraphicsDevice.DepthStencilState = DepthStencilState.None; GraphicsDevice.RasterizerState = RasterizerState.CullNone; GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap; fSkyBox.SetTexture(fSkyBoxTextures[fCurrentSkybox]); fSkyBox.Render(fCamera.Camera.ViewMatrix, fCamera.Camera.ProjectionMatrix, fCamera.Camera.Position, world); GraphicsDevice.BlendState = BlendState.Opaque; GraphicsDevice.DepthStencilState = DepthStencilState.Default; //GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; GraphicsDevice.RasterizerState = RasterizerState.CullNone; GraphicsDevice.SamplerStates[0] = SamplerState.LinearClamp; Model model = fModels[fCurrentModel]; Matrix wMatrix = Matrix.CreateScale(30) * world; Matrix[] modelTransforms = new Matrix[model.Bones.Count]; model.CopyAbsoluteBoneTransformsTo(modelTransforms); string shaderName = SHADERS[fCurrentShader]; foreach (ModelMesh mesh in model.Meshes) { try { if (shaderName.Equals(ORGINAL_SHADER)) { //With standard effect... foreach (BasicEffect x in mesh.Effects) { Matrix worldMatrix = modelTransforms[mesh.ParentBone.Index] * wMatrix; x.World = worldMatrix * mesh.ParentBone.Transform; x.EnableDefaultLighting(); x.PreferPerPixelLighting = true; x.View = view; x.Projection = projection; } mesh.Draw(); } else if (shaderName.Equals(ORGINAL_SHADER_TEXT)) { //With standard effect... foreach (BasicEffect x in mesh.Effects) { Matrix worldMatrix = modelTransforms[mesh.ParentBone.Index] * wMatrix; x.World = worldMatrix * mesh.ParentBone.Transform; x.EnableDefaultLighting(); x.PreferPerPixelLighting = true; x.View = view; x.Projection = projection; x.TextureEnabled = true; //x.AmbientLightColor = new Vector3(1.0f); //x.World = modelTransforms[mesh.ParentBone.Index]; } mesh.Draw(); } else { Effect effect = fShaders[fCurrentShader]; Effect[] originalEffects = new Effect[mesh.MeshParts.Count]; for (int i = 0; i < mesh.MeshParts.Count; i++) { originalEffects[i] = mesh.MeshParts[i].Effect; } try { for (int i = 0; i < mesh.MeshParts.Count; i++) { mesh.MeshParts[i].Effect = effect; Matrix worldMatrix = modelTransforms[mesh.ParentBone.Index] * wMatrix; Matrix worldInverseTransposeMatrix = Matrix.Transpose(Matrix.Invert(mesh.ParentBone.Transform * world)); Vector3 viewVector = new Vector3(fCamera.Camera.ViewMatrix.M13, fCamera.Camera.ViewMatrix.M23, fCamera.Camera.ViewMatrix.M33); effect.Parameters["World"].SetValue(worldMatrix * mesh.ParentBone.Transform); effect.Parameters["View"].SetValue(view); effect.Parameters["Projection"].SetValue(projection); switch (shaderName) { case "Ambient": effect.Parameters["AmbientColor"].SetValue(Color.Green.ToVector4()); effect.Parameters["AmbientIntensity"].SetValue(0.5f); break; case "DiffuseLightning": effect.Parameters["AmbientColor"].SetValue(Color.White.ToVector4()); effect.Parameters["AmbientIntensity"].SetValue(0.2f); effect.Parameters["WorldInverseTranspose"].SetValue(worldInverseTransposeMatrix); break; case "SpecularLightning": effect.Parameters["AmbientColor"].SetValue(Color.Red.ToVector4()); effect.Parameters["AmbientIntensity"].SetValue(0.5f); effect.Parameters["WorldInverseTranspose"].SetValue(worldInverseTransposeMatrix); effect.Parameters["ViewVector"].SetValue(viewVector); break; case "TextureShader": effect.Parameters["AmbientColor"].SetValue(1.0f); effect.Parameters["AmbientIntensity"].SetValue(0.1f); effect.Parameters["WorldInverseTranspose"].SetValue(worldInverseTransposeMatrix); effect.Parameters["ViewVector"].SetValue(viewVector); // TODO: now only the first texture in the model effect.Parameters["ModelTexture"].SetValue((originalEffects[i] as BasicEffect)?.Texture); break; case "NormalMapShader": //effect.Parameters["DiffuseLightDirection"].SetValue(new Vector3(0, 0.5f, 1)); //effect.Parameters["WorldInverseTranspose"].SetValue(worldInverseTransposeMatrix); //effect.Parameters["ModelTexture"].SetValue((originalEffects[i] as BasicEffect)?.Texture); // NORMAL MAP ONLY FOR HELICOPTER //effect.Parameters["NormalMap"].SetValue(fNormalMap); break; case "ToonShader": effect.Parameters["WorldInverseTranspose"].SetValue(worldInverseTransposeMatrix); effect.Parameters["Texture"].SetValue((originalEffects[i] as BasicEffect)?.Texture); break; } } mesh.Draw(); } finally { for (int i = 0; i < mesh.MeshParts.Count; i++) { mesh.MeshParts[i].Effect = originalEffects[i]; } } } } catch (Exception e) { } } base.Draw(gameTime); }